From c003de7a280ce71df483e15a60159a4abe330ae7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 3 Jul 2019 16:48:45 -0700 Subject: [PATCH] Allow allowJs and declaration to be used together This intorduces a new symbol-based declaration emitter - currently this is only used for JSON and JavaScript, as the output is likely worse than what the other declaration emitter is capable of. In addition, it is still incomplete - it does not yet support serializaing namespaces. --- src/compiler/checker.ts | 591 +++++++++++++++++- src/compiler/emitter.ts | 12 +- src/compiler/factory.ts | 5 + src/compiler/program.ts | 4 - src/compiler/transformers/declarations.ts | 23 +- src/compiler/types.ts | 7 + src/compiler/utilities.ts | 21 +- src/harness/compiler.ts | 21 +- src/harness/harness.ts | 6 +- .../unittests/tsbuild/resolveJsonModule.ts | 7 +- .../unittests/tscWatch/programUpdates.ts | 9 +- .../unittests/tsserver/projectErrors.ts | 9 +- .../reference/jsDeclarationsClasses.js | 476 ++++++++++++++ .../reference/jsDeclarationsClasses.symbols | 285 +++++++++ .../reference/jsDeclarationsClasses.types | 307 +++++++++ .../jsDeclarationsClassesErr.errors.txt | 136 ++++ .../reference/jsDeclarationsClassesErr.js | 290 +++++++++ .../jsDeclarationsClassesErr.symbols | 153 +++++ .../reference/jsDeclarationsClassesErr.types | 148 +++++ .../reference/jsDeclarationsDefault.js | 141 +++++ .../reference/jsDeclarationsDefault.symbols | 64 ++ .../reference/jsDeclarationsDefault.types | 68 ++ .../jsDeclarationsDefaultsErr.errors.txt | 34 + .../reference/jsDeclarationsDefaultsErr.js | 83 +++ .../jsDeclarationsDefaultsErr.symbols | 40 ++ .../reference/jsDeclarationsDefaultsErr.types | 43 ++ .../reference/jsDeclarationsEnums.errors.txt | 101 +++ .../reference/jsDeclarationsEnums.js | 170 +++++ .../reference/jsDeclarationsEnums.symbols | 134 ++++ .../reference/jsDeclarationsEnums.types | 164 +++++ .../reference/jsDeclarationsFunctions.js | 157 +++++ .../reference/jsDeclarationsFunctions.symbols | 115 ++++ .../reference/jsDeclarationsFunctions.types | 128 ++++ .../reference/jsDeclarationsFunctionsCjs.js | 167 +++++ .../jsDeclarationsFunctionsCjs.symbols | 197 ++++++ .../jsDeclarationsFunctionsCjs.types | 230 +++++++ .../jsDeclarationsInterfaces.errors.txt | 200 ++++++ .../reference/jsDeclarationsInterfaces.js | 238 +++++++ .../jsDeclarationsInterfaces.symbols | 280 +++++++++ .../reference/jsDeclarationsInterfaces.types | 189 ++++++ .../baselines/reference/jsDeclarationsJson.js | 69 ++ .../reference/jsDeclarationsJson.symbols | 33 + .../reference/jsDeclarationsJson.types | 52 ++ .../reference/jsDeclarationsTypeAliases.js | 63 ++ .../jsDeclarationsTypeAliases.symbols | 29 + .../reference/jsDeclarationsTypeAliases.types | 29 + ...DuplicateFunctionImplementation.errors.txt | 2 - ...pilationDuplicateFunctionImplementation.js | 1 + ...ImplementationFileOrderReversed.errors.txt | 2 - ...FunctionImplementationFileOrderReversed.js | 1 + ...ileCompilationDuplicateVariable.errors.txt | 9 - .../jsFileCompilationDuplicateVariable.js | 20 +- ...jsFileCompilationDuplicateVariable.symbols | 2 +- .../jsFileCompilationDuplicateVariable.types | 2 +- ...nDuplicateVariableErrorReported.errors.txt | 4 +- ...mpilationDuplicateVariableErrorReported.js | 5 +- ...tionDuplicateVariableErrorReported.symbols | 2 +- ...lationDuplicateVariableErrorReported.types | 2 +- ...FileCompilationEmitDeclarations.errors.txt | 12 - .../jsFileCompilationEmitDeclarations.js | 1 + ...lationEmitTrippleSlashReference.errors.txt | 16 - ...ileCompilationEmitTrippleSlashReference.js | 2 + ...onsWithJsFileReferenceWithNoOut.errors.txt | 4 +- ...eclarationsWithJsFileReferenceWithNoOut.js | 8 +- ...ationsWithJsFileReferenceWithNoOut.symbols | 2 +- ...arationsWithJsFileReferenceWithNoOut.types | 2 +- ...tionsWithJsFileReferenceWithOut.errors.txt | 17 - ...nDeclarationsWithJsFileReferenceWithOut.js | 4 +- ...arationsWithJsFileReferenceWithOut.symbols | 1 - ...clarationsWithJsFileReferenceWithOut.types | 1 - ...nsWithJsFileReferenceWithOutDir.errors.txt | 17 - ...clarationsWithJsFileReferenceWithOutDir.js | 4 +- ...eCompilationLetDeclarationOrder.errors.txt | 12 - .../jsFileCompilationLetDeclarationOrder.js | 1 + ...CompilationLetDeclarationOrder2.errors.txt | 2 - .../jsFileCompilationLetDeclarationOrder2.js | 1 + ...ationWithEnabledCompositeOption.errors.txt | 12 - ...leCompilationWithEnabledCompositeOption.js | 1 + .../amd/test.d.ts | 1 + ...entNamesNotSpecifiedWithAllowJs.errors.txt | 5 +- .../node/test.d.ts | 1 + .../amd/test.d.ts | 1 + ...ferentNamesSpecifiedWithAllowJs.errors.txt | 5 +- .../node/test.d.ts | 1 + ...eNameDtsNotSpecifiedWithAllowJs.errors.txt | 9 +- ...eNameDtsNotSpecifiedWithAllowJs.errors.txt | 9 +- .../requireOfJsonFileWithDeclaration.js | 6 + .../jsFileCompilationDuplicateVariable.ts | 2 +- ...mpilationDuplicateVariableErrorReported.ts | 2 +- ...eclarationsWithJsFileReferenceWithNoOut.ts | 2 +- ...nDeclarationsWithJsFileReferenceWithOut.ts | 1 - .../declarations/jsDeclarationsClasses.ts | 187 ++++++ .../declarations/jsDeclarationsClassesErr.ts | 76 +++ .../declarations/jsDeclarationsDefault.ts | 42 ++ .../declarations/jsDeclarationsDefaultsErr.ts | 30 + .../jsdoc/declarations/jsDeclarationsEnums.ts | 68 ++ .../declarations/jsDeclarationsFunctions.ts | 62 ++ .../jsDeclarationsFunctionsCjs.ts | 63 ++ .../declarations/jsDeclarationsInterfaces.ts | 125 ++++ .../jsdoc/declarations/jsDeclarationsJson.ts | 17 + .../declarations/jsDeclarationsTypeAliases.ts | 32 + ...pilationDuplicateFunctionImplementation.ts | 2 +- 102 files changed, 6455 insertions(+), 194 deletions(-) create mode 100644 tests/baselines/reference/jsDeclarationsClasses.js create mode 100644 tests/baselines/reference/jsDeclarationsClasses.symbols create mode 100644 tests/baselines/reference/jsDeclarationsClasses.types create mode 100644 tests/baselines/reference/jsDeclarationsClassesErr.errors.txt create mode 100644 tests/baselines/reference/jsDeclarationsClassesErr.js create mode 100644 tests/baselines/reference/jsDeclarationsClassesErr.symbols create mode 100644 tests/baselines/reference/jsDeclarationsClassesErr.types create mode 100644 tests/baselines/reference/jsDeclarationsDefault.js create mode 100644 tests/baselines/reference/jsDeclarationsDefault.symbols create mode 100644 tests/baselines/reference/jsDeclarationsDefault.types create mode 100644 tests/baselines/reference/jsDeclarationsDefaultsErr.errors.txt create mode 100644 tests/baselines/reference/jsDeclarationsDefaultsErr.js create mode 100644 tests/baselines/reference/jsDeclarationsDefaultsErr.symbols create mode 100644 tests/baselines/reference/jsDeclarationsDefaultsErr.types create mode 100644 tests/baselines/reference/jsDeclarationsEnums.errors.txt create mode 100644 tests/baselines/reference/jsDeclarationsEnums.js create mode 100644 tests/baselines/reference/jsDeclarationsEnums.symbols create mode 100644 tests/baselines/reference/jsDeclarationsEnums.types create mode 100644 tests/baselines/reference/jsDeclarationsFunctions.js create mode 100644 tests/baselines/reference/jsDeclarationsFunctions.symbols create mode 100644 tests/baselines/reference/jsDeclarationsFunctions.types create mode 100644 tests/baselines/reference/jsDeclarationsFunctionsCjs.js create mode 100644 tests/baselines/reference/jsDeclarationsFunctionsCjs.symbols create mode 100644 tests/baselines/reference/jsDeclarationsFunctionsCjs.types create mode 100644 tests/baselines/reference/jsDeclarationsInterfaces.errors.txt create mode 100644 tests/baselines/reference/jsDeclarationsInterfaces.js create mode 100644 tests/baselines/reference/jsDeclarationsInterfaces.symbols create mode 100644 tests/baselines/reference/jsDeclarationsInterfaces.types create mode 100644 tests/baselines/reference/jsDeclarationsJson.js create mode 100644 tests/baselines/reference/jsDeclarationsJson.symbols create mode 100644 tests/baselines/reference/jsDeclarationsJson.types create mode 100644 tests/baselines/reference/jsDeclarationsTypeAliases.js create mode 100644 tests/baselines/reference/jsDeclarationsTypeAliases.symbols create mode 100644 tests/baselines/reference/jsDeclarationsTypeAliases.types delete mode 100644 tests/baselines/reference/jsFileCompilationDuplicateVariable.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationEmitDeclarations.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationLetDeclarationOrder.errors.txt delete mode 100644 tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.errors.txt create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsClasses.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassesErr.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefault.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefaultsErr.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsEnums.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctions.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctionsCjs.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsInterfaces.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsJson.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeAliases.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 73e81913d6c50..0521929b6f5b7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2942,7 +2942,8 @@ namespace ts { */ function getContainersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined): Symbol[] | undefined { const container = getParentOfSymbol(symbol); - if (container) { + // Type parameters end up in the `members` lists but are not externally visible + if (container && !(symbol.flags & SymbolFlags.TypeParameter)) { const additionalContainers = mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer); const reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration); if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, SymbolFlags.Namespace, /*externalOnly*/ false)) { @@ -3106,6 +3107,27 @@ namespace ts { return result; } break; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.InterfaceDeclaration: + // Type parameters are bound into `members` lists so they can merge across declarations + // This is troublesome, since in all other respects, they behave like locals T.T + // TODO: the below is shared with similar code in `resolveName` - in fact, rephrasing all this symbol + // lookup logic in terms of `resolveName` would be nice + // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals + // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would + // trigger resolving late-bound names, which we may already be in the process of doing while we're here! + let table: UnderscoreEscapedMap | undefined; + // TODO: Should this filtered table be cached in some way? + (getSymbolOfNode(location as ClassLikeDeclaration | InterfaceDeclaration).members || emptySymbols).forEach((symbol, key) => { + if (symbol.flags & (SymbolFlags.Type & ~SymbolFlags.Assignment)) { + (table || (table = createSymbolTable())).set(key, symbol); + } + }); + if (table && (result = callback(table))) { + return result; + } + break; } } @@ -3543,6 +3565,8 @@ namespace ts { withContext(enclosingDeclaration, flags, tracker, context => symbolToParameterDeclaration(symbol, context)), typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeParameterToDeclaration(parameter, context)), + symbolTableToDeclarationStatements: (symbolTable: SymbolTable, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => + withContext(enclosingDeclaration, flags, tracker, context => symbolTableToDeclarationStatements(symbolTable, context)), }; function withContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined { @@ -4677,6 +4701,560 @@ namespace ts { } } } + + function cloneNodeBuilderContext(context: NodeBuilderContext): NodeBuilderContext { + const initial: NodeBuilderContext = { ...context }; + // Make type parameters created within this context not consume the name outside this context + // The symbol serializer ends up creating many sibling scopes that all need "seperate" contexts when + // it comes to naming things - within a normal `typeToTypeNode` call, the node builder only ever descends + // through the type tree, so the only cases where we could have used distinct sibling scopes was when there + // were multiple generic overloads with similar generated type parameter names + if (initial.typeParameterNames) { + initial.typeParameterNames = cloneMap(initial.typeParameterNames); + } + if (initial.typeParameterNamesByText) { + initial.typeParameterNamesByText = cloneMap(initial.typeParameterNamesByText); + } + if (initial.typeParameterSymbolList) { + initial.typeParameterSymbolList = cloneMap(initial.typeParameterSymbolList); + } + return initial; + } + + function symbolTableToDeclarationStatements(symbolTable: SymbolTable, context: NodeBuilderContext): Statement[] { + // TODO: Use `setOriginalNode` on original declarations where possible so these declarations see some kind of declaration mapping + const results: Statement[] = []; + const visitedSymbols: Map = createMap(); + const subcontext: typeof context = { + ...context, + usedSymbolNames: createMap(), + remappedSymbolNames: createMap(), + tracker: { + ...context.tracker, + trackSymbol: (sym, decl, meaning) => { + const accessibleChain = getAccessibleSymbolChain(sym, decl, meaning!, /*usOnlyExternalAliasing*/ false); + if (length(accessibleChain)) { + serializeSymbolRecursive(accessibleChain![0], /*isPrivate*/ true); + } + } + } + }; + symbolTable.forEach((_symbol, name) => { + subcontext.usedSymbolNames!.set(unescapeLeadingUnderscores(name), true); + }); + if (context.usedSymbolNames) { + context.usedSymbolNames.forEach((_, name) => { + subcontext.usedSymbolNames!.set(name, true); + }); + } + context = subcontext; + symbolTable.forEach((symbol, _name) => { + if (visitedSymbols.has("" + getSymbolId(symbol))) { + return; // Already printed + } + visitedSymbols.set("" + getSymbolId(symbol), true); + serializeSymbol(symbol, /*isPrivate*/ false); + }); + if (context.enclosingDeclaration && ((isSourceFile(context.enclosingDeclaration) && isExternalOrCommonJsModule(context.enclosingDeclaration)) || isModuleDeclaration(context.enclosingDeclaration)) && !hasScopeMarker(results) && some(results, needsScopeMarker)) { + results.push(createEmptyExports()); + } + // TODO: Cleanup pass: Merge redundant export declarations + return results; + + // Appends a `declare` and/or `export` modifier if the context requires it, and then adds `node` to `result` and returns `node` + // Note: This _mutates_ `node` without using `updateNode` - the assumption being that all nodes should be manufactured fresh by the node builder + function addResult(node: Statement, additionalModifierFlags: ModifierFlags) { + let newModifierFlags: ModifierFlags = ModifierFlags.None; + if (((additionalModifierFlags & ModifierFlags.Export) && context.enclosingDeclaration && + ((isSourceFile(context.enclosingDeclaration) && isExternalOrCommonJsModule(context.enclosingDeclaration)) || + (isAmbientModule(context.enclosingDeclaration) && !isGlobalScopeAugmentation(context.enclosingDeclaration)))) && + (isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || (isModuleDeclaration(node) && !isExternalModuleAugmentation(node) && !isGlobalScopeAugmentation(node)) || isInterfaceDeclaration(node) || isTypeDeclaration(node)) + ) { + // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private + newModifierFlags |= ModifierFlags.Export; + } + if (!(newModifierFlags & ModifierFlags.Export) && (!context.enclosingDeclaration || !(context.enclosingDeclaration.flags & NodeFlags.Ambient)) && (isEnumDeclaration(node) || isVariableStatement(node) || isFunctionDeclaration(node) || isClassDeclaration(node) || isModuleDeclaration(node))) { + // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope + newModifierFlags |= ModifierFlags.Ambient; + } + if ((additionalModifierFlags & ModifierFlags.Default) && (isClassDeclaration(node) || isInterfaceDeclaration(node) || isFunctionDeclaration(node))) { + newModifierFlags |= ModifierFlags.Default; + } + if (newModifierFlags) { + node.modifiers = createNodeArray(createModifiersFromModifierFlags(newModifierFlags | getModifierFlags(node))); + node.modifierFlagsCache = 0; // Reset computed flags cache + } + results.push(node); + return node; + } + + function serializeSymbol(symbol: Symbol, isPrivate: boolean) { + const oldContext = context; + context = cloneNodeBuilderContext(context); + const result = serializeSymbolWorker(symbol, isPrivate); + context = oldContext; + return result; + } + + function getInternalSymbolName(symbol: Symbol, localName: string) { + if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { + return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + } + if (localName === InternalSymbolName.Default) { + const flags = context.flags; + context.flags |= NodeBuilderFlags.InInitialEntityName; + const nameCandidate = getNameOfSymbolAsWritten(symbol, context); + context.flags = flags; + localName = isIdentifierText(nameCandidate, languageVersion) && !isStringANonContextualKeyword(nameCandidate) ? nameCandidate : getUnusedName(`_default`, symbol); + } + return localName; + } + + // Synthesize declarations for a symbol - might be an Interface, a Class, a Namespace, a Type, a Variable (const, let, or var), an Alias + // or a merge of some number of those. + // An interesting challenge is ensuring that when classes merge with namespaces and interfaces, is keeping + // each symbol in only one of the representations + // Also, synthesizing a default export of some kind + // If it's an alias: emit `export default ref` + // If it's a property: emit `export default _default` with a `_default` prop + // If it's a class/interface/function: emit a class/interface/function with a `default` modifier + // These forms can merge, eg (`export default 12; export default interface A {}`) + function serializeSymbolWorker(symbol: Symbol, isPrivate: boolean) { + const symbolName = unescapeLeadingUnderscores(symbol.escapedName); + const isDefault = symbol.escapedName === InternalSymbolName.Default; + if (isStringANonContextualKeyword(symbolName) && !isDefault) { + // Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :( + context.encounteredError = true; + // TODO: Issue error via symbol tracker? + return []; // If we need to emit a private with a keyword name, we're done for, since something else will try to refer to it by that name + } + const needsPostExportDefault = isDefault && ( + !!(symbol.flags & SymbolFlags.ExportDoesNotSupportDefaultModifier) + || (!!(symbol.flags & SymbolFlags.Function) && !!length(getPropertiesOfType(getTypeOfSymbol(symbol)))) + ) && !(symbol.flags & SymbolFlags.Alias); // An alias symbol should preclude needing to make an alias ourselves + if (needsPostExportDefault) { + isPrivate = true; + } + const localName = getInternalSymbolName(symbol, symbolName); + const modifierFlags = (!isPrivate ? ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ModifierFlags.Default : 0); + if (symbol.flags & SymbolFlags.Function) { + const type = getTypeOfSymbol(symbol); + const signatures = getSignaturesOfType(type, SignatureKind.Call); + for (const sig of signatures) { + // Each overload becomes a seperate function declaration, in order + const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context) as FunctionDeclaration; + decl.name = createIdentifier(localName); + addResult(decl, modifierFlags); + } + const props = getPropertiesOfType(type); + if (length(props)) { + // Add a namespace + const fakespace = createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier(localName), createModuleBlock([]), NodeFlags.Namespace); + fakespace.flags ^= NodeFlags.Synthesized; // unset synthesized so it is usable as an enclosing declaration + fakespace.parent = context.enclosingDeclaration as SourceFile | NamespaceDeclaration; + fakespace.locals = createSymbolTable(props); + fakespace.symbol = props[0].parent!; + const declarations = mapDefined(props, p => { + const subcontext = { ...context, enclosingDeclaration: fakespace }; + const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), typeToTypeNodeHelper(getTypeOfSymbol(p), subcontext), /*initializer*/ undefined); + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl])); + }); + fakespace.flags ^= NodeFlags.Synthesized; // reset synthesized + fakespace.parent = undefined!; + fakespace.locals = undefined!; + fakespace.symbol = undefined!; + fakespace.body = createModuleBlock(declarations); + addResult(fakespace, modifierFlags); // namespaces can never be default exported + } + } + if (symbol.flags & SymbolFlags.TypeAlias) { + const aliasType = getDeclaredTypeOfTypeAlias(symbol); + const typeParams = getSymbolLinks(symbol).typeParameters; + const typeParamDecls = map(typeParams, p => typeParameterToDeclaration(p, context)); + const oldFlags = context.flags; + context.flags |= NodeBuilderFlags.InTypeAlias; + addResult(createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, localName, typeParamDecls, typeToTypeNodeHelper(aliasType, context)), modifierFlags); + context.flags = oldFlags; + } + // Need to skip over export= symbols below - json source files get a single `Property` flagged + // symbol of name `export=` which needs to be handled like an alias. It's not great, but it is what it is. + if (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) && symbol.escapedName !== InternalSymbolName.ExportEquals) { + // `var` is `FunctionScopedVariable`, `const` and `let` are `BlockScopedVariable`, and `module.exports.thing =` is `Property` + const flags = !(symbol.flags & SymbolFlags.BlockScopedVariable) ? undefined : isConstVariable(symbol) ? NodeFlags.Const : NodeFlags.Let; + const name = (needsPostExportDefault || !(symbol.flags & SymbolFlags.Property)) ? localName : getUnusedName(localName, symbol); + const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([ + createVariableDeclaration(name, typeToTypeNodeHelper(getTypeOfSymbol(symbol), context)) + ], flags)); + addResult(statement, name !== localName ? modifierFlags & ~ModifierFlags.Export : modifierFlags); + if (name !== localName) { + Debug.assert(!isPrivate, "Had a local module member masquerading as an exported module member - this should not be possible"); + // We rename the variable declaration we generate for Property symbols since they may have a name which conflicts with a local declaration. Eg, + // `module.exports.g = g` - we want to make a variable declaration with type `typeof g` (ergo, we must emit `g`) + // and so we can't name the variable declaration `g` (since there's already a local `g`) - so we anonymize the local variable declaration and make + // an export declaration with an alias to the right name + addResult(createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(name, localName)])), ModifierFlags.None); + } + } + if (symbol.flags & SymbolFlags.Enum) { + addResult(createEnumDeclaration( + /*decorators*/ undefined, + createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? ModifierFlags.Const : 0), + localName, + map(filter(getPropertiesOfType(getTypeOfSymbol(symbol)), p => !!(p.flags & SymbolFlags.EnumMember)), p => { + // TODO: Handle computed names + // I hate that to get the initialized value we need to walk back to the declarations here; but there's no + // other way to get the possible const value of an enum member that I'm aware of, as the value is cached + // _on the declaration_, not on the declaration's symbol... + const initializedValue = p.declarations && p.declarations[0] && isEnumMember(p.declarations[0]) && getConstantValue(p.declarations[0] as EnumMember); + return createEnumMember(unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : createLiteral(initializedValue)); + }) + ), modifierFlags); + } + if (symbol.flags & SymbolFlags.Class) { + const localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + const typeParamDecls = map(localParams, p => typeParameterToDeclaration(p, context)); + const classType = getDeclaredTypeOfClassOrInterface(symbol); + const baseTypes = getBaseTypes(classType); // classes should only have one base type + const heritageClauses = !length(baseTypes) ? undefined : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, serializeBaseType))]; + const members = flatMap(getPropertiesOfType(classType), p => serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0])); + const staticType = getTypeOfSymbol(symbol); + const staticMembers = flatMap(getPropertiesOfType(staticType), p => serializePropertySymbolForClass(p, /*isStatic*/ true, /*staticBase*/ undefined)); + const constructors = serializeSignatures(SignatureKind.Construct, staticType, baseTypes[0], SyntaxKind.Constructor) as ConstructorDeclaration[]; + for (const c of constructors) { + // A constructor's return type and type parameters are supposed to be controlled by the enclosing class declaration + // `signatureToSignatureDeclarationHelper` appends them regardless, so for now we delete them here + c.type = undefined; + c.typeParameters = undefined; + } + const indexSignatures = serializeIndexSignatures(classType, baseTypes[0]); + addResult(createClassDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + localName, + typeParamDecls, + heritageClauses, + [...indexSignatures, ...staticMembers, ...constructors, ...members] + ), modifierFlags); + } + if (symbol.flags & SymbolFlags.Namespace) { + // TODO - Support namespace serialization + } + if (symbol.flags & SymbolFlags.Interface) { + const interfaceType = getDeclaredTypeOfClassOrInterface(symbol); + const localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + const typeParamDecls = map(localParams, p => typeParameterToDeclaration(p, context)); + const baseTypes = getBaseTypes(interfaceType); + const amalgamatedBase = length(baseTypes) ? getIntersectionType(baseTypes) : undefined; + const members = flatMap(getPropertiesOfType(interfaceType), p => serializePropertySymbolForInterface(p, amalgamatedBase)); + const callSignatures = serializeSignatures(SignatureKind.Call, interfaceType, amalgamatedBase, SyntaxKind.CallSignature) as CallSignatureDeclaration[]; + const constructSignatures = serializeSignatures(SignatureKind.Construct, interfaceType, amalgamatedBase, SyntaxKind.ConstructSignature) as ConstructSignatureDeclaration[]; + const indexSignatures = serializeIndexSignatures(interfaceType, amalgamatedBase); + + const heritageClauses = !length(baseTypes) ? undefined : [createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, serializeBaseType))]; + addResult(createInterfaceDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + localName, + typeParamDecls, + heritageClauses, + [...indexSignatures, ...constructSignatures, ...callSignatures, ...members] + ), modifierFlags); + } + if (symbol.flags & SymbolFlags.Alias) { + // exported alias symbol + // synthesize an alias, eg `export { symbolName as Name }` + // best to merge many of these together - need to mark the alias `symbol` points + // at as something we need to serialize as a private declaration as well + const node = getDeclarationOfAliasSymbol(symbol); + if (!node) return Debug.fail(); + const target = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true); + if (!target) return; + const targetName = getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)); + serializeSymbolRecursive(target, /*isPrivate*/ true); // the target may be within the same scope - attempt to serialize it first + switch (node.kind) { + case SyntaxKind.ImportEqualsDeclaration: + // Could be a local `import localName = ns.member` or + // an external `import localName = require("whatever")` + const isLocalImport = !target.parent!.valueDeclaration || !isSourceFile(target.parent!.valueDeclaration); + addResult(createImportEqualsDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createIdentifier(localName), + isLocalImport ? symbolToName(target, context, SymbolFlags.All, /*expectsIdentifier*/ false) : createExternalModuleReference(createLiteral(getSpecifierForModuleSymbol(symbol, context))) + ), isLocalImport ? modifierFlags : ModifierFlags.None); + break; + case SyntaxKind.NamespaceExportDeclaration: + // synthesize export * from "moduleReference" + // Straightforward - only one thing to do - make an export declaration + addResult(createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*exportClause*/ undefined, createLiteral(getSpecifierForModuleSymbol(symbol, context))), ModifierFlags.None); + break; + case SyntaxKind.ImportClause: + addResult(createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(createIdentifier(localName), /*namedBindings*/ undefined), + createLiteral(getSpecifierForModuleSymbol(target.parent!, context)) + ), ModifierFlags.None); + break; + case SyntaxKind.NamespaceImport: + addResult(createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*importClause*/ undefined, createNamespaceImport(createIdentifier(localName))), + createLiteral(getSpecifierForModuleSymbol(target.parent!, context)) + ), ModifierFlags.None); + break; + case SyntaxKind.ImportSpecifier: + addResult(createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*importClause*/ undefined, createNamedImports([ + createImportSpecifier(localName !== targetName ? createIdentifier(targetName) : undefined, createIdentifier(localName)) + ])), + createLiteral(getSpecifierForModuleSymbol(target.parent!, context)) + ), ModifierFlags.None); + break; + case SyntaxKind.ExportSpecifier: + // does not use localName because the symbol name in this case refers to the name in the exports table, which we must exactly preserve + serializeExportSpecifier(unescapeLeadingUnderscores(symbol.escapedName), targetName); + break; + case SyntaxKind.ExportAssignment: + serializeExportAssignment(symbol); + break; + case SyntaxKind.BinaryExpression: + // Could be best encoded as though an export specifier or as though an export assignment + // If name is default or export=, do an export assignment + // Otherwise do an export specifier + if (symbol.escapedName === InternalSymbolName.Default || symbol.escapedName === InternalSymbolName.ExportEquals) { + serializeExportAssignment(symbol); + } + else { + serializeExportSpecifier(localName, targetName); + } + break; + default: + return Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!"); + } + } + if (symbol.flags & SymbolFlags.Property && symbol.escapedName === InternalSymbolName.ExportEquals) { + serializeExportAssignment(symbol); + } + if (needsPostExportDefault) { + addResult(createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, createIdentifier(localName)), ModifierFlags.None); + } + } + + function serializeExportSpecifier(localName: string, targetName: string) { + addResult(createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(localName !== targetName ? targetName : undefined, localName)])), ModifierFlags.None); + } + + function serializeExportAssignment(symbol: Symbol) { + const name = unescapeLeadingUnderscores(symbol.escapedName); + const isExportEquals = name !== InternalSymbolName.Default; + // synthesize export = ref + // ref should refer to either be a locally scoped symbol which we need to emit, or + // a reference to another namespace/module which we may need to emit an `import` statement for + const aliasDecl = getDeclarationOfAliasSymbol(symbol); + // serialize what the alias points to, preserve the declaration's intializer + const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); + if (target) { + // TODO: Test `class A { member: Q; }; class Q { x: number }; module.exports = class Q { x: A; }` - the alias points at the class expression, + // but when hoisted to a declaration in the containing scope, its name shadows an outer name we need + // Also, in case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it + // eg, `namespace A { export class B {} }; exports = A.B;` + // Technically, this is all that's required in the case where the assignment is an entity name expression + const expr = getExportAssignmentExpression(aliasDecl as ExportAssignment | BinaryExpression); + const first = isEntityNameExpression(expr) ? getFirstIdentifier(expr) : undefined; + const referenced = first && getSymbolOfNode(first); + if (referenced) { + serializeSymbolRecursive(referenced, /*isPrivate*/ true); + } + + results.push(createExportAssignment( + /*decorators*/ undefined, + /*modifiers*/ undefined, + isExportEquals, + symbolToExpression(target, context, SymbolFlags.All) + )); + } + else { + // serialize as an anonymous property declaration + const varName = getUnusedName(name, symbol); + const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([ + // We have to use `getWidenedType` here since the object within a json file is unwidened within the file + // (Unwidened types can only exist in expression contexts and should never be serialized) + createVariableDeclaration(varName, typeToTypeNodeHelper(getWidenedType(getTypeOfSymbol(symbol)), context)) + ], NodeFlags.Const)); + addResult(statement, ModifierFlags.None); + results.push(createExportAssignment( + /*decorators*/ undefined, + /*modifiers*/ undefined, + isExportEquals, + createIdentifier(varName) + )); + } + } + + function makeSerializePropertySymbol(createProperty: ( + decorators: ReadonlyArray | undefined, + modifiers: ReadonlyArray | undefined, + name: string | PropertyName, + questionOrExclamationToken: QuestionToken | undefined, + type: TypeNode | undefined, + initializer: Expression | undefined + ) => T, methodKind: SyntaxKind): (p: Symbol, isStatic: boolean, baseType: Type | undefined) => (T | T[]) { + return function serializePropertySymbol(p: Symbol, isStatic: boolean, baseType: Type | undefined) { + if (p.flags & SymbolFlags.Prototype || (baseType && getPropertyOfType(baseType, p.escapedName) + && isReadonlySymbol(getPropertyOfType(baseType, p.escapedName)!) === isReadonlySymbol(p) + && (p.flags & SymbolFlags.Optional) === (getPropertyOfType(baseType, p.escapedName)!.flags & SymbolFlags.Optional) + && isTypeIdenticalTo(getTypeOfSymbol(p), getTypeOfPropertyOfType(baseType, p.escapedName)!))) { + return []; + } + const staticFlag = isStatic ? ModifierFlags.Static : 0; + if (p.flags & SymbolFlags.Property || p.flags & SymbolFlags.Accessor) { + return createProperty( + /*decorators*/ undefined, + createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | staticFlag), + unescapeLeadingUnderscores(p.escapedName), // TODO: Computed names!?!?! + p.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined, + typeToTypeNodeHelper(getTypeOfSymbol(p), context), + /*initializer*/ undefined // interface members can't have initializers, however class members _can_ + ); + } + if (p.flags & SymbolFlags.Method) { + const type = getTypeOfSymbol(p); + const memberName = unescapeLeadingUnderscores(p.escapedName); // TODO: Computed names!?!?! + const signatures = getSignaturesOfType(type, SignatureKind.Call); + const results = []; + for (const sig of signatures) { + // Each overload becomes a seperate method declaration, in order + const decl = signatureToSignatureDeclarationHelper(sig, methodKind, context) as MethodDeclaration; + decl.name = createIdentifier(memberName); + if (staticFlag) { + decl.modifiers = createNodeArray(createModifiersFromModifierFlags(staticFlag)); + } + if (p.flags & SymbolFlags.Optional) { + decl.questionToken = createToken(SyntaxKind.QuestionToken); + } + results.push(decl); + } + return results as unknown as T[]; + } + // The `Constructor`'s symbol isn't in the class's properties lists, obviously, since it's a signature on the static + return Debug.fail(`Unhandled class member kind! ${(p as any).__debugFlags || p.flags}`); + }; + } + + function serializePropertySymbolForClass(p: Symbol, isStatic: boolean, baseType: Type | undefined) { + return makeSerializePropertySymbol(createProperty, SyntaxKind.MethodDeclaration)(p, isStatic, baseType); + } + + function serializePropertySymbolForInterface(p: Symbol, baseType: Type | undefined) { + return makeSerializePropertySymbol((_decorators, mods, name, question, type, initializer) => createPropertySignature(mods, name, question, type, initializer), SyntaxKind.MethodSignature)(p, /*isStatic*/ false, baseType); + } + + function serializeSignatures(kind: SignatureKind, input: Type, baseType: Type | undefined, outputKind: SyntaxKind) { + const signatures = getSignaturesOfType(input, kind); + if (!baseType && every(signatures, s => length(s.parameters) === 0)) { + return []; // No base type, every constructor is empty - elide the extraneous `constructor()` + } + if (baseType) { + // If there is a base type, if every signature in the class is identical to a signature in the baseType, elide all the declarations + const baseSigs = getSignaturesOfType(baseType, SignatureKind.Construct); + if (!length(baseSigs) && every(signatures, s => length(s.parameters) === 0)) { + return []; // Base had no explicit signatures, if all our signatures are also implicit, return an empty list + } + if (baseSigs.length === signatures.length) { + let failed = false; + for (let i = 0; i < baseSigs.length; i++) { + if (!compareSignaturesIdentical(signatures[i], baseSigs[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { + failed = true; + break; + } + } + if (!failed) { + return []; // Every signature was identical - elide constructor list as it is inherited + } + } + } + + const results = []; + for (const sig of signatures) { + // Each overload becomes a seperate constructor declaration, in order + const decl = signatureToSignatureDeclarationHelper(sig, outputKind, context); + results.push(decl); + } + return results; + } + + function serializeIndexSignatures(input: Type, baseType: Type | undefined) { + const results: IndexSignatureDeclaration[] = []; + for (const type of [IndexKind.String, IndexKind.Number]) { + const info = getIndexInfoOfType(input, type); + if (info) { + if (baseType) { + const baseInfo = getIndexInfoOfType(baseType, type); + if (baseInfo) { + if (isTypeIdenticalTo(info.type, baseInfo.type)) { + continue; // elide identical index signatures + } + } + } + results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context)); + } + } + return results; + } + + function serializeBaseType(t: Type) { + let typeArgs: TypeNode[] | undefined; + let reference: Expression; + if ((t as TypeReference).target) { + typeArgs = map((t as TypeReference).typeArguments, t => typeToTypeNodeHelper(t, context)); + reference = symbolToExpression((t as TypeReference).target.symbol, context, SymbolFlags.Type); + } + else if (t.symbol) { + reference = symbolToExpression(t.symbol, context, SymbolFlags.Type); + } + else { + // TODO: can non-reference, un-symboled types be in interface `extends`? If so, how do we make a clause that they refer to + return Debug.fail(`Unsure how to declaration emit serialize interface base type: ${typeToString(t)}`); + } + return createExpressionWithTypeArguments(typeArgs, reference); + } + + function serializeSymbolRecursive(symbol: Symbol, isPrivate: boolean) { + if (visitedSymbols.has("" + getSymbolId(symbol))) { + return; // Already printed + } + visitedSymbols.set("" + getSymbolId(symbol), true); + // Only actually serialize symbols within the correct enclosing declaration, otherwise do nothing with the out-of-context symbol + if (length(symbol.declarations) && some(symbol.declarations, d => !!findAncestor(d, n => n === context.enclosingDeclaration))) { + serializeSymbol(symbol, isPrivate); + } + } + + function getUnusedName(input: string, symbol: Symbol): string { + if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) { + return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!; + } + if (input === InternalSymbolName.Default) { + input = "_default"; + } + else if (input === InternalSymbolName.ExportEquals) { + input = "_exports"; + } + let i = 0; + const original = input; + while (context.usedSymbolNames!.has(input)) { + i++; + input = `${original}_${i}`; + } + context.usedSymbolNames!.set(input, true); + context.remappedSymbolNames!.set("" + getSymbolId(symbol), input); + return input; + } + } } function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer?: EmitTextWriter): string { @@ -4761,6 +5339,8 @@ namespace ts { typeParameterSymbolList?: Map; typeParameterNames?: Map; typeParameterNamesByText?: Map; + usedSymbolNames?: Map; + remappedSymbolNames?: Map; } function isDefaultBindingContext(location: Node) { @@ -31784,6 +32364,15 @@ namespace ts { const parseNode = getParseTreeNode(node); const parseDecl = getParseTreeNode(decl); return !!parseNode && !!parseDecl && (isVariableDeclaration(parseDecl) || isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl); + }, + getDeclarationStatementsForSourceFile: (node, flags, tracker) => { + const n = getParseTreeNode(node) as SourceFile; + Debug.assert(n && n.kind === SyntaxKind.SourceFile, "Non-sourcefile node passed into getDeclarationsForSourceFile"); + const sym = getSymbolOfNode(node); + if (!sym) { + return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker); + } + return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker); } }; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a1207c9b892c9..b57ccc28c3ad8 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -97,9 +97,7 @@ namespace ts { comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath; const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options); - // For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error - const isJs = isSourceFileJS(sourceFile); - const declarationFilePath = ((forceDtsPaths || getEmitDeclarations(options)) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined; + const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined; const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath: undefined }; } @@ -351,17 +349,16 @@ namespace ts { declarationFilePath: string | undefined, declarationMapPath: string | undefined, relativeToBuildInfo: (path: string) => string) { - if (!sourceFileOrBundle || !(declarationFilePath && !isInJSFile(sourceFileOrBundle))) { + if (!sourceFileOrBundle || !declarationFilePath) { return; } const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles; // Setup and perform the transformation to retrieve declarations from the input files - const nonJsFiles = filter(sourceFiles, isSourceFileNotJS); - const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles; + const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(sourceFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : sourceFiles; if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) { // Checker wont collect the linked aliases since thats only done when declaration is enabled. // Do that here when emitting only dts files - nonJsFiles.forEach(collectLinkedAliases); + sourceFiles.forEach(collectLinkedAliases); } const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false); if (length(declarationTransform.diagnostics)) { @@ -615,6 +612,7 @@ namespace ts { getAllAccessorDeclarations: notImplemented, getSymbolOfExternalModuleSpecifier: notImplemented, isBindingCapturedByNode: notImplemented, + getDeclarationStatementsForSourceFile: notImplemented, }; /*@internal*/ diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index f88950f531a37..9ed7b02398cf4 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2139,6 +2139,11 @@ namespace ts { : node; } + /* @internal */ + export function createEmptyExports() { + return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined); + } + export function createNamedExports(elements: ReadonlyArray) { const node = createSynthesizedNode(SyntaxKind.NamedExports); node.elements = createNodeArray(elements); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 664e2d0319d9a..aed890411065b 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2906,10 +2906,6 @@ namespace ts { } } - if (!options.noEmit && options.allowJs && getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", getEmitDeclarationOptionName(options)); - } - if (options.checkJs && !options.allowJs) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index bb939f7d4f1f1..025e598cbfb93 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,11 +1,8 @@ /*@internal*/ namespace ts { export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined { - if (file && isSourceFileJS(file)) { - return []; // No declaration diagnostics for js for now - } const compilerOptions = host.getCompilerOptions(); - const result = transformNodes(resolver, host, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJS), [transformDeclarations], /*allowDtsFiles*/ false); + const result = transformNodes(resolver, host, compilerOptions, file ? [file] : host.getSourceFiles(), [transformDeclarations], /*allowDtsFiles*/ false); return result.diagnostics; } @@ -190,15 +187,11 @@ namespace ts { } } - function createEmptyExports() { - return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined); - } - function transformRoot(node: Bundle): Bundle; function transformRoot(node: SourceFile): SourceFile; function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle; function transformRoot(node: SourceFile | Bundle) { - if (node.kind === SyntaxKind.SourceFile && (node.isDeclarationFile || isSourceFileJS(node))) { + if (node.kind === SyntaxKind.SourceFile && node.isDeclarationFile) { return node; } @@ -209,7 +202,10 @@ namespace ts { let hasNoDefaultLib = false; const bundle = createBundle(map(node.sourceFiles, sourceFile => { - if (sourceFile.isDeclarationFile || isSourceFileJS(sourceFile)) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 + if (sourceFile.isDeclarationFile) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217 + if (isSourceFileJS(sourceFile)) { + return updateSourceFileNode(sourceFile, resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker) || emptyArray); + } hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib; currentSourceFile = sourceFile; enclosingDeclaration = sourceFile; @@ -257,6 +253,9 @@ namespace ts { refs.forEach(referenceVisitor); return bundle; } + else if (isSourceFileJS(node)) { + return updateSourceFileNode(node, resolver.getDeclarationStatementsForSourceFile(node, declarationEmitNodeBuilderFlags, symbolTracker) || emptyArray); + } // Single source file needsDeclare = true; @@ -710,10 +709,6 @@ namespace ts { return isAnyImportOrReExport(result) || isExportAssignment(result) || hasModifier(result, ModifierFlags.Export); } - function needsScopeMarker(result: LateVisibilityPaintedStatement | ExportAssignment) { - return !isAnyImportOrReExport(result) && !isExportAssignment(result) && !hasModifier(result, ModifierFlags.Export) && !isAmbientModule(result); - } - function visitDeclarationSubtree(input: Node): VisitResult { if (shouldStripInternal(input)) return; if (isDeclaration(input)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a88580f9b1240..7d8e4094b37a3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3620,6 +3620,7 @@ namespace ts { getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations; getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined; isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean; + getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, tracker: SymbolTracker): Statement[] | undefined; } export const enum SymbolFlags { @@ -3700,6 +3701,12 @@ namespace ts { ClassMember = Method | Accessor | Property, + /* @internal */ + ExportSupportsDefaultModifier = Class | Function | Interface, + + /* @internal */ + ExportDoesNotSupportDefaultModifier = ~ExportSupportsDefaultModifier, + /* @internal */ // The set of things we consider semantically classifiable. Used to speed up the LS during // classification. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3203e10f370e7..08ea796a52c6d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2561,10 +2561,14 @@ namespace ts { } export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean { - const e = isExportAssignment(node) ? node.expression : node.right; + const e = getExportAssignmentExpression(node); return isEntityNameExpression(e) || isClassExpression(e); } + export function getExportAssignmentExpression(node: ExportAssignment | BinaryExpression): Expression { + return isExportAssignment(node) ? node.expression : node.right; + } + export function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceDeclaration) { const baseType = getClassExtendsHeritageElement(node); if (baseType && isInJSFile(node)) { @@ -6656,6 +6660,21 @@ namespace ts { return false; } + /* @internal */ + export function isScopeMarker(node: Node) { + return isExportAssignment(node) || isExportDeclaration(node); + } + + /* @internal */ + export function hasScopeMarker(statements: ReadonlyArray) { + return some(statements, isScopeMarker); + } + + /* @internal */ + export function needsScopeMarker(result: Statement) { + return !isAnyImportOrReExport(result) && !isExportAssignment(result) && !hasModifier(result, ModifierFlags.Export) && !isAmbientModule(result); + } + /* @internal */ export function isForInOrOfStatement(node: Node): node is ForInOrOfStatement { return node.kind === SyntaxKind.ForInStatement || node.kind === SyntaxKind.ForOfStatement; diff --git a/src/harness/compiler.ts b/src/harness/compiler.ts index 70bda90ef32db..6be1b71f7405b 100644 --- a/src/harness/compiler.ts +++ b/src/harness/compiler.ts @@ -219,14 +219,19 @@ namespace compiler { return vpath.changeExtension(path, ext); } - public getNumberOfJsFiles() { - let count = this.js.size; - this.js.forEach(document => { - if (ts.fileExtensionIs(document.file, ts.Extension.Json)) { - count--; - } - }); - return count; + public getNumberOfJsFiles(includeJson: boolean) { + if (includeJson) { + return this.js.size; + } + else { + let count = this.js.size; + this.js.forEach(document => { + if (ts.fileExtensionIs(document.file, ts.Extension.Json)) { + count--; + } + }); + return count; + } } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index fe5ec3443229a..ede78ee36859a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -883,7 +883,7 @@ namespace Harness { throw new Error("Only declaration files should be generated when emitDeclarationOnly:true"); } } - else if (result.dts.size !== result.getNumberOfJsFiles()) { + else if (result.dts.size !== result.getNumberOfJsFiles(/*includeJson*/ true)) { throw new Error("There were no errors and declFiles generated did not match number of js files generated"); } } @@ -902,7 +902,7 @@ namespace Harness { if (vpath.isDeclaration(file.unitName) || vpath.isJson(file.unitName)) { dtsFiles.push(file); } - else if (vpath.isTypeScript(file.unitName)) { + else if (vpath.isTypeScript(file.unitName) || (vpath.isJavaScript(file.unitName) && options.allowJs)) { const declFile = findResultCodeFile(file.unitName); if (declFile && !findUnit(declFile.file, declInputFiles) && !findUnit(declFile.file, declOtherFiles)) { dtsFiles.push({ unitName: declFile.file, content: utils.removeByteOrderMark(declFile.text) }); @@ -1267,7 +1267,7 @@ namespace Harness { return; } else if (options.sourceMap || declMaps) { - if (result.maps.size !== (result.getNumberOfJsFiles() * (declMaps && options.sourceMap ? 2 : 1))) { + if (result.maps.size !== ((options.sourceMap ? result.getNumberOfJsFiles(/*includeJson*/ false) : 0) + (declMaps ? result.getNumberOfJsFiles(/*includeJson*/ true) : 0))) { throw new Error("Number of sourcemap files should be same as js files."); } diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index 7793ef5375c5d..657474f5bac4a 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -47,7 +47,12 @@ namespace ts { export default hello.hello`); const allExpectedOutputs = ["/src/dist/src/index.js", "/src/dist/src/index.d.ts", "/src/dist/src/index.json"]; - verifyProjectWithResolveJsonModuleWithFs(fs, "/src/tsconfig_withIncludeOfJson.json", allExpectedOutputs); + verifyProjectWithResolveJsonModuleWithFs( + fs, + "/src/tsconfig_withIncludeOfJson.json", + allExpectedOutputs, + [Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, "/src/dist/src/index.d.ts"] + ); }); it("with resolveJsonModule and files containing json file", () => { diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index b322c08bfe7f8..811ec98cb9f5d 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -885,8 +885,8 @@ namespace ts.tscWatch { // More comment`; const configFileContentAfterComment = ` "compilerOptions": { - "allowJs": true, - "declaration": true + "inlineSourceMap": true, + "mapRoot": "./" } }`; const configFileContentWithComment = configFileContentBeforeComment + configFileContentComment + configFileContentAfterComment; @@ -900,8 +900,9 @@ namespace ts.tscWatch { const host = createWatchedSystem(files); const watch = createWatchOfConfigFile(configFile.path, host); const errors = () => [ - getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"), - getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration") + getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"inlineSourceMap"'), '"inlineSourceMap"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"), + getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"mapRoot"'), '"mapRoot"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"), + getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"mapRoot"'), '"mapRoot"'.length, Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap") ]; const intialErrors = errors(); checkOutputErrorsInitial(host, intialErrors); diff --git a/src/testRunner/unittests/tsserver/projectErrors.ts b/src/testRunner/unittests/tsserver/projectErrors.ts index 10e6d3b972d46..67cfae2755df2 100644 --- a/src/testRunner/unittests/tsserver/projectErrors.ts +++ b/src/testRunner/unittests/tsserver/projectErrors.ts @@ -849,8 +849,8 @@ declare module '@custom/plugin' { // comment`; const configFileContentAfterComment = ` "compilerOptions": { - "allowJs": true, - "declaration": true + "inlineSourceMap": true, + "mapRoot": "./" } }`; const configFileContentWithComment = configFileContentBeforeComment + configFileContentComment + configFileContentAfterComment; @@ -874,7 +874,7 @@ declare module '@custom/plugin' { seq: 2, arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true } }).response as ReadonlyArray; - assert.isTrue(diags.length === 2); + assert.isTrue(diags.length === 3); configFile.content = configFileContentWithoutCommentLine; host.reloadFS([file, configFile]); @@ -885,10 +885,11 @@ declare module '@custom/plugin' { seq: 2, arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true } }).response as ReadonlyArray; - assert.isTrue(diagsAfterEdit.length === 2); + assert.isTrue(diagsAfterEdit.length === 3); verifyDiagnostic(diags[0], diagsAfterEdit[0]); verifyDiagnostic(diags[1], diagsAfterEdit[1]); + verifyDiagnostic(diags[2], diagsAfterEdit[2]); function verifyDiagnostic(beforeEditDiag: server.protocol.DiagnosticWithLinePosition, afterEditDiag: server.protocol.DiagnosticWithLinePosition) { assert.equal(beforeEditDiag.message, afterEditDiag.message); diff --git a/tests/baselines/reference/jsDeclarationsClasses.js b/tests/baselines/reference/jsDeclarationsClasses.js new file mode 100644 index 0000000000000..5aaac3608a9b8 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClasses.js @@ -0,0 +1,476 @@ +//// [index.js] +export class A {} + +export class B { + static cat = "cat"; +} + +export class C { + static Cls = class {} +} + +export class D { + /** + * @param {number} a + * @param {number} b + */ + constructor(a, b) {} +} + +/** + * @template T,U + */ +export class E { + /** + * @type {T & U} + */ + field; + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {T & U} + * @readonly + */ + readonlyField; + + initializedField = 12; + + /** + * @return {U} + */ + get f1() { return /** @type {*} */(null); } + + /** + * @param {U} _p + */ + set f1(_p) {} + + /** + * @return {U} + */ + get f2() { return /** @type {*} */(null); } + + /** + * @param {U} _p + */ + set f3(_p) {} + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} + + + /** + * @type {string} + */ + static staticField; + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {string} + * @readonly + */ + static staticReadonlyField; + + static staticInitializedField = 12; + + /** + * @return {string} + */ + static get s1() { return ""; } + + /** + * @param {string} _p + */ + static set s1(_p) {} + + /** + * @return {string} + */ + static get s2() { return ""; } + + /** + * @param {string} _p + */ + static set s3(_p) {} +} + +/** + * @template T,U + */ +export class F { + /** + * @type {T & U} + */ + field; + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} + + /** + * @template A,B + * @param {A} a + * @param {B} b + */ + static create(a, b) { return new F(a, b); } +} + +class G {} + +export { G }; + +class HH {} + +export { HH as H }; + +export class I {} +export { I as II }; + +export { J as JJ }; +export class J {} + + +export class K { + constructor() { + this.p1 = 12; + this.p2 = "ok"; + } + + method() { + return this.p1; + } +} + +export class L extends K {} + +export class M extends null { + constructor() { + this.prop = 12; + } +} + + +/** + * @template T + */ +export class N extends L { + /** + * @param {T} param + */ + constructor(param) { + super(); + this.another = param; + } +} + +/** + * @template U + * @extends {N} + */ +export class O extends N { + /** + * @param {U} param + */ + constructor(param) { + super(param); + this.another2 = param; + } +} + + +//// [index.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +var B = /** @class */ (function () { + function B() { + } + B.cat = "cat"; + return B; +}()); +exports.B = B; +var C = /** @class */ (function () { + function C() { + } + C.Cls = /** @class */ (function () { + function class_1() { + } + return class_1; + }()); + return C; +}()); +exports.C = C; +var D = /** @class */ (function () { + /** + * @param {number} a + * @param {number} b + */ + function D(a, b) { + } + return D; +}()); +exports.D = D; +/** + * @template T,U + */ +var E = /** @class */ (function () { + /** + * @param {T} a + * @param {U} b + */ + function E(a, b) { + this.initializedField = 12; + } + Object.defineProperty(E.prototype, "f1", { + /** + * @return {U} + */ + get: function () { return /** @type {*} */ (null); }, + /** + * @param {U} _p + */ + set: function (_p) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(E.prototype, "f2", { + /** + * @return {U} + */ + get: function () { return /** @type {*} */ (null); }, + enumerable: true, + configurable: true + }); + Object.defineProperty(E.prototype, "f3", { + /** + * @param {U} _p + */ + set: function (_p) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(E, "s1", { + /** + * @return {string} + */ + get: function () { return ""; }, + /** + * @param {string} _p + */ + set: function (_p) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(E, "s2", { + /** + * @return {string} + */ + get: function () { return ""; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(E, "s3", { + /** + * @param {string} _p + */ + set: function (_p) { }, + enumerable: true, + configurable: true + }); + E.staticInitializedField = 12; + return E; +}()); +exports.E = E; +/** + * @template T,U + */ +var F = /** @class */ (function () { + /** + * @param {T} a + * @param {U} b + */ + function F(a, b) { + } + /** + * @template A,B + * @param {A} a + * @param {B} b + */ + F.create = function (a, b) { return new F(a, b); }; + return F; +}()); +exports.F = F; +var G = /** @class */ (function () { + function G() { + } + return G; +}()); +exports.G = G; +var HH = /** @class */ (function () { + function HH() { + } + return HH; +}()); +exports.H = HH; +var I = /** @class */ (function () { + function I() { + } + return I; +}()); +exports.I = I; +exports.II = I; +var J = /** @class */ (function () { + function J() { + } + return J; +}()); +exports.JJ = J; +exports.J = J; +var K = /** @class */ (function () { + function K() { + this.p1 = 12; + this.p2 = "ok"; + } + K.prototype.method = function () { + return this.p1; + }; + return K; +}()); +exports.K = K; +var L = /** @class */ (function (_super) { + __extends(L, _super); + function L() { + return _super !== null && _super.apply(this, arguments) || this; + } + return L; +}(K)); +exports.L = L; +var M = /** @class */ (function (_super) { + __extends(M, _super); + function M() { + _this.prop = 12; + } + return M; +}(null)); +exports.M = M; +/** + * @template T + */ +var N = /** @class */ (function (_super) { + __extends(N, _super); + /** + * @param {T} param + */ + function N(param) { + var _this = _super.call(this) || this; + _this.another = param; + return _this; + } + return N; +}(L)); +exports.N = N; +/** + * @template U + * @extends {N} + */ +var O = /** @class */ (function (_super) { + __extends(O, _super); + /** + * @param {U} param + */ + function O(param) { + var _this = _super.call(this, param) || this; + _this.another2 = param; + return _this; + } + return O; +}(N)); +exports.O = O; + + +//// [index.d.ts] +export class A { +} +export class B { + static cat: string; +} +export class C { + static Cls: { + new (): {}; + }; +} +export class D { + constructor(a: number, b: number); +} +export class E { + static staticField: string; + static staticReadonlyField: string; + static staticInitializedField: number; + static s1: string; + static readonly s2: string; + static s3: string; + constructor(a: T, b: U); + field: T & U; + readonlyField: T & U; + initializedField: number; + f1: U; + readonly f2: U; + f3: U; +} +export class F { + static create(a: A_1, b: B_1): F; + constructor(a: T, b: U); + field: T & U; +} +declare class G { +} +export { G }; +declare class HH { +} +export { HH as H }; +export class I { +} +export { I as II }; +declare class J { +} +export { J as JJ }; +export class K { + p1: number; + p2: string; + method(): number; +} +export class L extends K { +} +export class M { + prop: number; +} +export class N extends L { + constructor(param: T); + another: T; +} +export class O extends N { + constructor(param: U); + another2: U; +} diff --git a/tests/baselines/reference/jsDeclarationsClasses.symbols b/tests/baselines/reference/jsDeclarationsClasses.symbols new file mode 100644 index 0000000000000..50f6b574fbef2 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClasses.symbols @@ -0,0 +1,285 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export class A {} +>A : Symbol(A, Decl(index.js, 0, 0)) + +export class B { +>B : Symbol(B, Decl(index.js, 0, 17)) + + static cat = "cat"; +>cat : Symbol(B.cat, Decl(index.js, 2, 16)) +} + +export class C { +>C : Symbol(C, Decl(index.js, 4, 1)) + + static Cls = class {} +>Cls : Symbol(C.Cls, Decl(index.js, 6, 16)) +} + +export class D { +>D : Symbol(D, Decl(index.js, 8, 1)) + + /** + * @param {number} a + * @param {number} b + */ + constructor(a, b) {} +>a : Symbol(a, Decl(index.js, 15, 16)) +>b : Symbol(b, Decl(index.js, 15, 18)) +} + +/** + * @template T,U + */ +export class E { +>E : Symbol(E, Decl(index.js, 16, 1)) + + /** + * @type {T & U} + */ + field; +>field : Symbol(E.field, Decl(index.js, 21, 16)) + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {T & U} + * @readonly + */ + readonlyField; +>readonlyField : Symbol(E.readonlyField, Decl(index.js, 25, 10)) + + initializedField = 12; +>initializedField : Symbol(E.initializedField, Decl(index.js, 32, 18)) + + /** + * @return {U} + */ + get f1() { return /** @type {*} */(null); } +>f1 : Symbol(E.f1, Decl(index.js, 34, 26), Decl(index.js, 39, 47)) + + /** + * @param {U} _p + */ + set f1(_p) {} +>f1 : Symbol(E.f1, Decl(index.js, 34, 26), Decl(index.js, 39, 47)) +>_p : Symbol(_p, Decl(index.js, 44, 11)) + + /** + * @return {U} + */ + get f2() { return /** @type {*} */(null); } +>f2 : Symbol(E.f2, Decl(index.js, 44, 17)) + + /** + * @param {U} _p + */ + set f3(_p) {} +>f3 : Symbol(E.f3, Decl(index.js, 49, 47)) +>_p : Symbol(_p, Decl(index.js, 54, 11)) + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} +>a : Symbol(a, Decl(index.js, 60, 16)) +>b : Symbol(b, Decl(index.js, 60, 18)) + + + /** + * @type {string} + */ + static staticField; +>staticField : Symbol(E.staticField, Decl(index.js, 60, 24)) + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {string} + * @readonly + */ + static staticReadonlyField; +>staticReadonlyField : Symbol(E.staticReadonlyField, Decl(index.js, 66, 23)) + + static staticInitializedField = 12; +>staticInitializedField : Symbol(E.staticInitializedField, Decl(index.js, 73, 31)) + + /** + * @return {string} + */ + static get s1() { return ""; } +>s1 : Symbol(E.s1, Decl(index.js, 75, 39), Decl(index.js, 80, 34)) + + /** + * @param {string} _p + */ + static set s1(_p) {} +>s1 : Symbol(E.s1, Decl(index.js, 75, 39), Decl(index.js, 80, 34)) +>_p : Symbol(_p, Decl(index.js, 85, 18)) + + /** + * @return {string} + */ + static get s2() { return ""; } +>s2 : Symbol(E.s2, Decl(index.js, 85, 24)) + + /** + * @param {string} _p + */ + static set s3(_p) {} +>s3 : Symbol(E.s3, Decl(index.js, 90, 34)) +>_p : Symbol(_p, Decl(index.js, 95, 18)) +} + +/** + * @template T,U + */ +export class F { +>F : Symbol(F, Decl(index.js, 96, 1)) + + /** + * @type {T & U} + */ + field; +>field : Symbol(F.field, Decl(index.js, 101, 16)) + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} +>a : Symbol(a, Decl(index.js, 110, 16)) +>b : Symbol(b, Decl(index.js, 110, 18)) + + /** + * @template A,B + * @param {A} a + * @param {B} b + */ + static create(a, b) { return new F(a, b); } +>create : Symbol(F.create, Decl(index.js, 110, 24)) +>a : Symbol(a, Decl(index.js, 117, 18)) +>b : Symbol(b, Decl(index.js, 117, 20)) +>F : Symbol(F, Decl(index.js, 96, 1)) +>a : Symbol(a, Decl(index.js, 117, 18)) +>b : Symbol(b, Decl(index.js, 117, 20)) +} + +class G {} +>G : Symbol(G, Decl(index.js, 118, 1)) + +export { G }; +>G : Symbol(G, Decl(index.js, 122, 8)) + +class HH {} +>HH : Symbol(HH, Decl(index.js, 122, 13)) + +export { HH as H }; +>HH : Symbol(HH, Decl(index.js, 122, 13)) +>H : Symbol(H, Decl(index.js, 126, 8)) + +export class I {} +>I : Symbol(I, Decl(index.js, 126, 19)) + +export { I as II }; +>I : Symbol(I, Decl(index.js, 126, 19)) +>II : Symbol(II, Decl(index.js, 129, 8)) + +export { J as JJ }; +>J : Symbol(J, Decl(index.js, 131, 19)) +>JJ : Symbol(JJ, Decl(index.js, 131, 8)) + +export class J {} +>J : Symbol(J, Decl(index.js, 131, 19)) + + +export class K { +>K : Symbol(K, Decl(index.js, 132, 17)) + + constructor() { + this.p1 = 12; +>this.p1 : Symbol(K.p1, Decl(index.js, 136, 19)) +>this : Symbol(K, Decl(index.js, 132, 17)) +>p1 : Symbol(K.p1, Decl(index.js, 136, 19)) + + this.p2 = "ok"; +>this.p2 : Symbol(K.p2, Decl(index.js, 137, 21)) +>this : Symbol(K, Decl(index.js, 132, 17)) +>p2 : Symbol(K.p2, Decl(index.js, 137, 21)) + } + + method() { +>method : Symbol(K.method, Decl(index.js, 139, 5)) + + return this.p1; +>this.p1 : Symbol(K.p1, Decl(index.js, 136, 19)) +>this : Symbol(K, Decl(index.js, 132, 17)) +>p1 : Symbol(K.p1, Decl(index.js, 136, 19)) + } +} + +export class L extends K {} +>L : Symbol(L, Decl(index.js, 144, 1)) +>K : Symbol(K, Decl(index.js, 132, 17)) + +export class M extends null { +>M : Symbol(M, Decl(index.js, 146, 27)) + + constructor() { + this.prop = 12; +>this.prop : Symbol(M.prop, Decl(index.js, 149, 19)) +>this : Symbol(M, Decl(index.js, 146, 27)) +>prop : Symbol(M.prop, Decl(index.js, 149, 19)) + } +} + + +/** + * @template T + */ +export class N extends L { +>N : Symbol(N, Decl(index.js, 152, 1)) +>L : Symbol(L, Decl(index.js, 144, 1)) + + /** + * @param {T} param + */ + constructor(param) { +>param : Symbol(param, Decl(index.js, 162, 16)) + + super(); +>super : Symbol(L, Decl(index.js, 144, 1)) + + this.another = param; +>this.another : Symbol(N.another, Decl(index.js, 163, 16)) +>this : Symbol(N, Decl(index.js, 152, 1)) +>another : Symbol(N.another, Decl(index.js, 163, 16)) +>param : Symbol(param, Decl(index.js, 162, 16)) + } +} + +/** + * @template U + * @extends {N} + */ +export class O extends N { +>O : Symbol(O, Decl(index.js, 166, 1)) +>N : Symbol(N, Decl(index.js, 152, 1)) + + /** + * @param {U} param + */ + constructor(param) { +>param : Symbol(param, Decl(index.js, 176, 16)) + + super(param); +>super : Symbol(N, Decl(index.js, 152, 1)) +>param : Symbol(param, Decl(index.js, 176, 16)) + + this.another2 = param; +>this.another2 : Symbol(O.another2, Decl(index.js, 177, 21)) +>this : Symbol(O, Decl(index.js, 166, 1)) +>another2 : Symbol(O.another2, Decl(index.js, 177, 21)) +>param : Symbol(param, Decl(index.js, 176, 16)) + } +} + diff --git a/tests/baselines/reference/jsDeclarationsClasses.types b/tests/baselines/reference/jsDeclarationsClasses.types new file mode 100644 index 0000000000000..f4df752c9dded --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClasses.types @@ -0,0 +1,307 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export class A {} +>A : A + +export class B { +>B : B + + static cat = "cat"; +>cat : string +>"cat" : "cat" +} + +export class C { +>C : C + + static Cls = class {} +>Cls : typeof (Anonymous class) +>class {} : typeof (Anonymous class) +} + +export class D { +>D : D + + /** + * @param {number} a + * @param {number} b + */ + constructor(a, b) {} +>a : number +>b : number +} + +/** + * @template T,U + */ +export class E { +>E : E + + /** + * @type {T & U} + */ + field; +>field : T & U + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {T & U} + * @readonly + */ + readonlyField; +>readonlyField : T & U + + initializedField = 12; +>initializedField : number +>12 : 12 + + /** + * @return {U} + */ + get f1() { return /** @type {*} */(null); } +>f1 : U +>(null) : any +>null : null + + /** + * @param {U} _p + */ + set f1(_p) {} +>f1 : U +>_p : U + + /** + * @return {U} + */ + get f2() { return /** @type {*} */(null); } +>f2 : U +>(null) : any +>null : null + + /** + * @param {U} _p + */ + set f3(_p) {} +>f3 : U +>_p : U + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} +>a : T +>b : U + + + /** + * @type {string} + */ + static staticField; +>staticField : string + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {string} + * @readonly + */ + static staticReadonlyField; +>staticReadonlyField : string + + static staticInitializedField = 12; +>staticInitializedField : number +>12 : 12 + + /** + * @return {string} + */ + static get s1() { return ""; } +>s1 : string +>"" : "" + + /** + * @param {string} _p + */ + static set s1(_p) {} +>s1 : string +>_p : string + + /** + * @return {string} + */ + static get s2() { return ""; } +>s2 : string +>"" : "" + + /** + * @param {string} _p + */ + static set s3(_p) {} +>s3 : string +>_p : string +} + +/** + * @template T,U + */ +export class F { +>F : F + + /** + * @type {T & U} + */ + field; +>field : T & U + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} +>a : T +>b : U + + /** + * @template A,B + * @param {A} a + * @param {B} b + */ + static create(a, b) { return new F(a, b); } +>create : (a: A, b: B) => F +>a : A +>b : B +>new F(a, b) : F +>F : typeof F +>a : A +>b : B +} + +class G {} +>G : G + +export { G }; +>G : typeof G + +class HH {} +>HH : HH + +export { HH as H }; +>HH : typeof HH +>H : typeof HH + +export class I {} +>I : I + +export { I as II }; +>I : typeof I +>II : typeof I + +export { J as JJ }; +>J : typeof J +>JJ : typeof J + +export class J {} +>J : J + + +export class K { +>K : K + + constructor() { + this.p1 = 12; +>this.p1 = 12 : 12 +>this.p1 : number +>this : this +>p1 : number +>12 : 12 + + this.p2 = "ok"; +>this.p2 = "ok" : "ok" +>this.p2 : string +>this : this +>p2 : string +>"ok" : "ok" + } + + method() { +>method : () => number + + return this.p1; +>this.p1 : number +>this : this +>p1 : number + } +} + +export class L extends K {} +>L : L +>K : K + +export class M extends null { +>M : M +>null : null + + constructor() { + this.prop = 12; +>this.prop = 12 : 12 +>this.prop : number +>this : this +>prop : number +>12 : 12 + } +} + + +/** + * @template T + */ +export class N extends L { +>N : N +>L : L + + /** + * @param {T} param + */ + constructor(param) { +>param : T + + super(); +>super() : void +>super : typeof L + + this.another = param; +>this.another = param : T +>this.another : T +>this : this +>another : T +>param : T + } +} + +/** + * @template U + * @extends {N} + */ +export class O extends N { +>O : O +>N : N + + /** + * @param {U} param + */ + constructor(param) { +>param : U + + super(param); +>super(param) : void +>super : typeof N +>param : U + + this.another2 = param; +>this.another2 = param : U +>this.another2 : U +>this : this +>another2 : U +>param : U + } +} + diff --git a/tests/baselines/reference/jsDeclarationsClassesErr.errors.txt b/tests/baselines/reference/jsDeclarationsClassesErr.errors.txt new file mode 100644 index 0000000000000..ef78bf109c843 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClassesErr.errors.txt @@ -0,0 +1,136 @@ +tests/cases/conformance/jsdoc/declarations/index.js(4,16): error TS8004: 'type parameter declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(5,12): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(8,16): error TS8004: 'type parameter declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(8,29): error TS8011: 'type arguments' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(9,12): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(13,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(19,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(23,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(27,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(28,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(32,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(39,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(43,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(47,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(48,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(52,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(53,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(59,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(63,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(67,11): error TS8010: 'types' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(68,11): error TS8010: 'types' can only be used in a .ts file. + + +==== tests/cases/conformance/jsdoc/declarations/index.js (21 errors) ==== + // Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), + // but we should be able to synthesize declarations from the symbols regardless + + export class M { + ~ +!!! error TS8004: 'type parameter declarations' can only be used in a .ts file. + field: T; + ~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class N extends M { + ~ +!!! error TS8004: 'type parameter declarations' can only be used in a .ts file. + ~ +!!! error TS8011: 'type arguments' can only be used in a .ts file. + other: U; + ~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class O { + [idx: string]: string; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class P extends O {} + + export class Q extends O { + [idx: string]: "ok"; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class R extends O { + [idx: number]: "ok"; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class S extends O { + [idx: string]: "ok"; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + [idx: number]: never; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class T { + [idx: number]: string; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class U extends T {} + + + export class V extends T { + [idx: string]: string; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class W extends T { + [idx: number]: "ok"; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class X extends T { + [idx: string]: string; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + [idx: number]: "ok"; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class Y { + [idx: string]: {x: number}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + [idx: number]: {x: number, y: number}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class Z extends Y {} + + export class AA extends Y { + [idx: string]: {x: number, y: number}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class BB extends Y { + [idx: number]: {x: 0, y: 0}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + + export class CC extends Y { + [idx: string]: {x: number, y: number}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + [idx: number]: {x: 0, y: 0}; + ~~~~~~ +!!! error TS8010: 'types' can only be used in a .ts file. + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsClassesErr.js b/tests/baselines/reference/jsDeclarationsClassesErr.js new file mode 100644 index 0000000000000..0241e9693c673 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClassesErr.js @@ -0,0 +1,290 @@ +//// [index.js] +// Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export class M { + field: T; +} + +export class N extends M { + other: U; +} + +export class O { + [idx: string]: string; +} + +export class P extends O {} + +export class Q extends O { + [idx: string]: "ok"; +} + +export class R extends O { + [idx: number]: "ok"; +} + +export class S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} + +export class T { + [idx: number]: string; +} + +export class U extends T {} + + +export class V extends T { + [idx: string]: string; +} + +export class W extends T { + [idx: number]: "ok"; +} + +export class X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} + +export class Y { + [idx: string]: {x: number}; + [idx: number]: {x: number, y: number}; +} + +export class Z extends Y {} + +export class AA extends Y { + [idx: string]: {x: number, y: number}; +} + +export class BB extends Y { + [idx: number]: {x: 0, y: 0}; +} + +export class CC extends Y { + [idx: string]: {x: number, y: number}; + [idx: number]: {x: 0, y: 0}; +} + + +//// [index.js] +"use strict"; +// Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var M = /** @class */ (function () { + function M() { + } + return M; +}()); +exports.M = M; +var N = /** @class */ (function (_super) { + __extends(N, _super); + function N() { + return _super !== null && _super.apply(this, arguments) || this; + } + return N; +}(M)); +exports.N = N; +var O = /** @class */ (function () { + function O() { + } + return O; +}()); +exports.O = O; +var P = /** @class */ (function (_super) { + __extends(P, _super); + function P() { + return _super !== null && _super.apply(this, arguments) || this; + } + return P; +}(O)); +exports.P = P; +var Q = /** @class */ (function (_super) { + __extends(Q, _super); + function Q() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Q; +}(O)); +exports.Q = Q; +var R = /** @class */ (function (_super) { + __extends(R, _super); + function R() { + return _super !== null && _super.apply(this, arguments) || this; + } + return R; +}(O)); +exports.R = R; +var S = /** @class */ (function (_super) { + __extends(S, _super); + function S() { + return _super !== null && _super.apply(this, arguments) || this; + } + return S; +}(O)); +exports.S = S; +var T = /** @class */ (function () { + function T() { + } + return T; +}()); +exports.T = T; +var U = /** @class */ (function (_super) { + __extends(U, _super); + function U() { + return _super !== null && _super.apply(this, arguments) || this; + } + return U; +}(T)); +exports.U = U; +var V = /** @class */ (function (_super) { + __extends(V, _super); + function V() { + return _super !== null && _super.apply(this, arguments) || this; + } + return V; +}(T)); +exports.V = V; +var W = /** @class */ (function (_super) { + __extends(W, _super); + function W() { + return _super !== null && _super.apply(this, arguments) || this; + } + return W; +}(T)); +exports.W = W; +var X = /** @class */ (function (_super) { + __extends(X, _super); + function X() { + return _super !== null && _super.apply(this, arguments) || this; + } + return X; +}(T)); +exports.X = X; +var Y = /** @class */ (function () { + function Y() { + } + return Y; +}()); +exports.Y = Y; +var Z = /** @class */ (function (_super) { + __extends(Z, _super); + function Z() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Z; +}(Y)); +exports.Z = Z; +var AA = /** @class */ (function (_super) { + __extends(AA, _super); + function AA() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AA; +}(Y)); +exports.AA = AA; +var BB = /** @class */ (function (_super) { + __extends(BB, _super); + function BB() { + return _super !== null && _super.apply(this, arguments) || this; + } + return BB; +}(Y)); +exports.BB = BB; +var CC = /** @class */ (function (_super) { + __extends(CC, _super); + function CC() { + return _super !== null && _super.apply(this, arguments) || this; + } + return CC; +}(Y)); +exports.CC = CC; + + +//// [index.d.ts] +export class M { + field: T_1; +} +export class N extends M { + other: U_1; +} +export class O { + [idx: string]: string; +} +export class P extends O { +} +export class Q extends O { + [idx: string]: "ok"; +} +export class R extends O { + [idx: number]: "ok"; +} +export class S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} +export class T { + [idx: number]: string; +} +export class U extends T { +} +export class V extends T { + [idx: string]: string; +} +export class W extends T { + [idx: number]: "ok"; +} +export class X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} +export class Y { + [idx: string]: { + x: number; + }; + [idx: number]: { + x: number; + y: number; + }; +} +export class Z extends Y { +} +export class AA extends Y { + [idx: string]: { + x: number; + y: number; + }; +} +export class BB extends Y { + [idx: number]: { + x: 0; + y: 0; + }; +} +export class CC extends Y { + [idx: string]: { + x: number; + y: number; + }; + [idx: number]: { + x: 0; + y: 0; + }; +} diff --git a/tests/baselines/reference/jsDeclarationsClassesErr.symbols b/tests/baselines/reference/jsDeclarationsClassesErr.symbols new file mode 100644 index 0000000000000..3e0d026a83f66 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClassesErr.symbols @@ -0,0 +1,153 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export class M { +>M : Symbol(M, Decl(index.js, 0, 0)) +>T : Symbol(T, Decl(index.js, 3, 15)) + + field: T; +>field : Symbol(M.field, Decl(index.js, 3, 19)) +>T : Symbol(T, Decl(index.js, 3, 15)) +} + +export class N extends M { +>N : Symbol(N, Decl(index.js, 5, 1)) +>U : Symbol(U, Decl(index.js, 7, 15)) +>M : Symbol(M, Decl(index.js, 0, 0)) +>U : Symbol(U, Decl(index.js, 7, 15)) + + other: U; +>other : Symbol(N.other, Decl(index.js, 7, 32)) +>U : Symbol(U, Decl(index.js, 7, 15)) +} + +export class O { +>O : Symbol(O, Decl(index.js, 9, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 12, 5)) +} + +export class P extends O {} +>P : Symbol(P, Decl(index.js, 13, 1)) +>O : Symbol(O, Decl(index.js, 9, 1)) + +export class Q extends O { +>Q : Symbol(Q, Decl(index.js, 15, 27)) +>O : Symbol(O, Decl(index.js, 9, 1)) + + [idx: string]: "ok"; +>idx : Symbol(idx, Decl(index.js, 18, 5)) +} + +export class R extends O { +>R : Symbol(R, Decl(index.js, 19, 1)) +>O : Symbol(O, Decl(index.js, 9, 1)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 22, 5)) +} + +export class S extends O { +>S : Symbol(S, Decl(index.js, 23, 1)) +>O : Symbol(O, Decl(index.js, 9, 1)) + + [idx: string]: "ok"; +>idx : Symbol(idx, Decl(index.js, 26, 5)) + + [idx: number]: never; +>idx : Symbol(idx, Decl(index.js, 27, 5)) +} + +export class T { +>T : Symbol(T, Decl(index.js, 28, 1)) + + [idx: number]: string; +>idx : Symbol(idx, Decl(index.js, 31, 5)) +} + +export class U extends T {} +>U : Symbol(U, Decl(index.js, 32, 1)) +>T : Symbol(T, Decl(index.js, 28, 1)) + + +export class V extends T { +>V : Symbol(V, Decl(index.js, 34, 27)) +>T : Symbol(T, Decl(index.js, 28, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 38, 5)) +} + +export class W extends T { +>W : Symbol(W, Decl(index.js, 39, 1)) +>T : Symbol(T, Decl(index.js, 28, 1)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 42, 5)) +} + +export class X extends T { +>X : Symbol(X, Decl(index.js, 43, 1)) +>T : Symbol(T, Decl(index.js, 28, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 46, 5)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 47, 5)) +} + +export class Y { +>Y : Symbol(Y, Decl(index.js, 48, 1)) + + [idx: string]: {x: number}; +>idx : Symbol(idx, Decl(index.js, 51, 5)) +>x : Symbol(x, Decl(index.js, 51, 20)) + + [idx: number]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 52, 5)) +>x : Symbol(x, Decl(index.js, 52, 20)) +>y : Symbol(y, Decl(index.js, 52, 30)) +} + +export class Z extends Y {} +>Z : Symbol(Z, Decl(index.js, 53, 1)) +>Y : Symbol(Y, Decl(index.js, 48, 1)) + +export class AA extends Y { +>AA : Symbol(AA, Decl(index.js, 55, 27)) +>Y : Symbol(Y, Decl(index.js, 48, 1)) + + [idx: string]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 58, 5)) +>x : Symbol(x, Decl(index.js, 58, 20)) +>y : Symbol(y, Decl(index.js, 58, 30)) +} + +export class BB extends Y { +>BB : Symbol(BB, Decl(index.js, 59, 1)) +>Y : Symbol(Y, Decl(index.js, 48, 1)) + + [idx: number]: {x: 0, y: 0}; +>idx : Symbol(idx, Decl(index.js, 62, 5)) +>x : Symbol(x, Decl(index.js, 62, 20)) +>y : Symbol(y, Decl(index.js, 62, 25)) +} + +export class CC extends Y { +>CC : Symbol(CC, Decl(index.js, 63, 1)) +>Y : Symbol(Y, Decl(index.js, 48, 1)) + + [idx: string]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 66, 5)) +>x : Symbol(x, Decl(index.js, 66, 20)) +>y : Symbol(y, Decl(index.js, 66, 30)) + + [idx: number]: {x: 0, y: 0}; +>idx : Symbol(idx, Decl(index.js, 67, 5)) +>x : Symbol(x, Decl(index.js, 67, 20)) +>y : Symbol(y, Decl(index.js, 67, 25)) +} + diff --git a/tests/baselines/reference/jsDeclarationsClassesErr.types b/tests/baselines/reference/jsDeclarationsClassesErr.types new file mode 100644 index 0000000000000..83827f2658c9c --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsClassesErr.types @@ -0,0 +1,148 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export class M { +>M : M + + field: T; +>field : T +} + +export class N extends M { +>N : N +>M : M + + other: U; +>other : U +} + +export class O { +>O : O + + [idx: string]: string; +>idx : string +} + +export class P extends O {} +>P : P +>O : O + +export class Q extends O { +>Q : Q +>O : O + + [idx: string]: "ok"; +>idx : string +} + +export class R extends O { +>R : R +>O : O + + [idx: number]: "ok"; +>idx : number +} + +export class S extends O { +>S : S +>O : O + + [idx: string]: "ok"; +>idx : string + + [idx: number]: never; +>idx : number +} + +export class T { +>T : T + + [idx: number]: string; +>idx : number +} + +export class U extends T {} +>U : U +>T : T + + +export class V extends T { +>V : V +>T : T + + [idx: string]: string; +>idx : string +} + +export class W extends T { +>W : W +>T : T + + [idx: number]: "ok"; +>idx : number +} + +export class X extends T { +>X : X +>T : T + + [idx: string]: string; +>idx : string + + [idx: number]: "ok"; +>idx : number +} + +export class Y { +>Y : Y + + [idx: string]: {x: number}; +>idx : string +>x : number + + [idx: number]: {x: number, y: number}; +>idx : number +>x : number +>y : number +} + +export class Z extends Y {} +>Z : Z +>Y : Y + +export class AA extends Y { +>AA : AA +>Y : Y + + [idx: string]: {x: number, y: number}; +>idx : string +>x : number +>y : number +} + +export class BB extends Y { +>BB : BB +>Y : Y + + [idx: number]: {x: 0, y: 0}; +>idx : number +>x : 0 +>y : 0 +} + +export class CC extends Y { +>CC : CC +>Y : Y + + [idx: string]: {x: number, y: number}; +>idx : string +>x : number +>y : number + + [idx: number]: {x: 0, y: 0}; +>idx : number +>x : 0 +>y : 0 +} + diff --git a/tests/baselines/reference/jsDeclarationsDefault.js b/tests/baselines/reference/jsDeclarationsDefault.js new file mode 100644 index 0000000000000..4fc0d3247ea92 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefault.js @@ -0,0 +1,141 @@ +//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefault.ts] //// + +//// [index1.js] +export default 12; + +//// [index2.js] +export default function foo() { + return foo; +} +export const x = foo; +export { foo as bar }; + +//// [index3.js] +export default class Foo { + a = /** @type {Foo} */(null); +}; +export const X = Foo; +export { Foo as Bar }; + +//// [index4.js] +import Fab from "./index3"; +class Bar extends Fab { + x = /** @type {Bar} */(null); +} +export default Bar; + +//// [index5.js] +// merge type alias and const (OK) +export default 12; +/** + * @typedef {string | number} default + */ + +//// [index6.js] +// merge type alias and function (OK) +export default function func() {}; +/** + * @typedef {string | number} default + */ + + +//// [index1.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = 12; +//// [index2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function foo() { + return foo; +} +exports.default = foo; +exports.bar = foo; +exports.x = foo; +//// [index3.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Foo = /** @class */ (function () { + function Foo() { + this.a = (null); + } + return Foo; +}()); +exports.Bar = Foo; +exports.default = Foo; +; +exports.X = Foo; +//// [index4.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var index3_1 = require("./index3"); +var Bar = /** @class */ (function (_super) { + __extends(Bar, _super); + function Bar() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.x = (null); + return _this; + } + return Bar; +}(index3_1.default)); +exports.default = Bar; +//// [index5.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// merge type alias and const (OK) +exports.default = 12; +/** + * @typedef {string | number} default + */ +//// [index6.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// merge type alias and function (OK) +function func() { } +exports.default = func; +; +/** + * @typedef {string | number} default + */ + + +//// [index1.d.ts] +declare var _default: 12; +export default _default; +//// [index2.d.ts] +export default function foo(): typeof foo; +export const x: typeof foo; +export { foo as bar }; +//// [index3.d.ts] +export default class Foo { + a: Foo; +} +export const X: typeof Foo; +export { Foo as Bar }; +//// [index4.d.ts] +import Fab from "./index3"; +declare class Bar extends Fab { + x: Bar; +} +export default Bar; +//// [index5.d.ts] +type _default = string | number; +declare var _default: 12; +export default _default; +//// [index6.d.ts] +declare function func(): void; +type func = string | number; +export default func; diff --git a/tests/baselines/reference/jsDeclarationsDefault.symbols b/tests/baselines/reference/jsDeclarationsDefault.symbols new file mode 100644 index 0000000000000..4436c83d40ec0 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefault.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/jsdoc/declarations/index1.js === +export default 12; +No type information for this code. +No type information for this code.=== tests/cases/conformance/jsdoc/declarations/index2.js === +export default function foo() { +>foo : Symbol(foo, Decl(index2.js, 0, 0)) + + return foo; +>foo : Symbol(foo, Decl(index2.js, 0, 0)) +} +export const x = foo; +>x : Symbol(x, Decl(index2.js, 3, 12)) +>foo : Symbol(foo, Decl(index2.js, 0, 0)) + +export { foo as bar }; +>foo : Symbol(foo, Decl(index2.js, 0, 0)) +>bar : Symbol(bar, Decl(index2.js, 4, 8)) + +=== tests/cases/conformance/jsdoc/declarations/index3.js === +export default class Foo { +>Foo : Symbol(Foo, Decl(index3.js, 0, 0)) + + a = /** @type {Foo} */(null); +>a : Symbol(Foo.a, Decl(index3.js, 0, 26)) + +}; +export const X = Foo; +>X : Symbol(X, Decl(index3.js, 3, 12)) +>Foo : Symbol(Foo, Decl(index3.js, 0, 0)) + +export { Foo as Bar }; +>Foo : Symbol(Foo, Decl(index3.js, 0, 0)) +>Bar : Symbol(Bar, Decl(index3.js, 4, 8)) + +=== tests/cases/conformance/jsdoc/declarations/index4.js === +import Fab from "./index3"; +>Fab : Symbol(Fab, Decl(index4.js, 0, 6)) + +class Bar extends Fab { +>Bar : Symbol(Bar, Decl(index4.js, 0, 27)) +>Fab : Symbol(Fab, Decl(index4.js, 0, 6)) + + x = /** @type {Bar} */(null); +>x : Symbol(Bar.x, Decl(index4.js, 1, 23)) +} +export default Bar; +>Bar : Symbol(Bar, Decl(index4.js, 0, 27)) + +=== tests/cases/conformance/jsdoc/declarations/index5.js === +// merge type alias and const (OK) +No type information for this code.export default 12; +No type information for this code./** +No type information for this code. * @typedef {string | number} default +No type information for this code. */ +No type information for this code. +No type information for this code.=== tests/cases/conformance/jsdoc/declarations/index6.js === +// merge type alias and function (OK) +export default function func() {}; +>func : Symbol(func, Decl(index6.js, 0, 0), Decl(index6.js, 3, 3)) + +/** + * @typedef {string | number} default + */ + diff --git a/tests/baselines/reference/jsDeclarationsDefault.types b/tests/baselines/reference/jsDeclarationsDefault.types new file mode 100644 index 0000000000000..df45a2a221c2f --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefault.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/jsdoc/declarations/index1.js === +export default 12; +No type information for this code. +No type information for this code.=== tests/cases/conformance/jsdoc/declarations/index2.js === +export default function foo() { +>foo : () => typeof foo + + return foo; +>foo : () => typeof foo +} +export const x = foo; +>x : () => typeof foo +>foo : () => typeof foo + +export { foo as bar }; +>foo : () => typeof foo +>bar : () => typeof foo + +=== tests/cases/conformance/jsdoc/declarations/index3.js === +export default class Foo { +>Foo : Foo + + a = /** @type {Foo} */(null); +>a : Foo +>(null) : Foo +>null : null + +}; +export const X = Foo; +>X : typeof Foo +>Foo : typeof Foo + +export { Foo as Bar }; +>Foo : typeof Foo +>Bar : typeof Foo + +=== tests/cases/conformance/jsdoc/declarations/index4.js === +import Fab from "./index3"; +>Fab : typeof Fab + +class Bar extends Fab { +>Bar : Bar +>Fab : Fab + + x = /** @type {Bar} */(null); +>x : Bar +>(null) : Bar +>null : null +} +export default Bar; +>Bar : Bar + +=== tests/cases/conformance/jsdoc/declarations/index5.js === +// merge type alias and const (OK) +No type information for this code.export default 12; +No type information for this code./** +No type information for this code. * @typedef {string | number} default +No type information for this code. */ +No type information for this code. +No type information for this code.=== tests/cases/conformance/jsdoc/declarations/index6.js === +// merge type alias and function (OK) +export default function func() {}; +>func : () => void + +/** + * @typedef {string | number} default + */ + diff --git a/tests/baselines/reference/jsDeclarationsDefaultsErr.errors.txt b/tests/baselines/reference/jsDeclarationsDefaultsErr.errors.txt new file mode 100644 index 0000000000000..1940b1cde98ae --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefaultsErr.errors.txt @@ -0,0 +1,34 @@ +tests/cases/conformance/jsdoc/declarations/index2.js(2,22): error TS2300: Duplicate identifier 'C'. +tests/cases/conformance/jsdoc/declarations/index2.js(4,31): error TS2300: Duplicate identifier 'default'. + + +==== tests/cases/conformance/jsdoc/declarations/index1.js (0 errors) ==== + // merge type alias and alias (should error, see #32367) + class Cls { + x = 12; + static y = "ok" + } + export default Cls; + /** + * @typedef {string | number} default + */ + +==== tests/cases/conformance/jsdoc/declarations/index2.js (2 errors) ==== + // merge type alias and class (error message improvement needed, see #32368) + export default class C {}; + ~ +!!! error TS2300: Duplicate identifier 'C'. + /** + * @typedef {string | number} default + ~~~~~~~ +!!! error TS2300: Duplicate identifier 'default'. + */ + +==== tests/cases/conformance/jsdoc/declarations/index3.js (0 errors) ==== + // merge type alias and variable (beharior is borked, see #32366) + const x = 12; + export {x as default}; + /** + * @typedef {string | number} default + */ + \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsDefaultsErr.js b/tests/baselines/reference/jsDeclarationsDefaultsErr.js new file mode 100644 index 0000000000000..923bf1683ac13 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefaultsErr.js @@ -0,0 +1,83 @@ +//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefaultsErr.ts] //// + +//// [index1.js] +// merge type alias and alias (should error, see #32367) +class Cls { + x = 12; + static y = "ok" +} +export default Cls; +/** + * @typedef {string | number} default + */ + +//// [index2.js] +// merge type alias and class (error message improvement needed, see #32368) +export default class C {}; +/** + * @typedef {string | number} default + */ + +//// [index3.js] +// merge type alias and variable (beharior is borked, see #32366) +const x = 12; +export {x as default}; +/** + * @typedef {string | number} default + */ + + +//// [index1.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// merge type alias and alias (should error, see #32367) +var Cls = /** @class */ (function () { + function Cls() { + this.x = 12; + } + Cls.y = "ok"; + return Cls; +}()); +exports.default = Cls; +/** + * @typedef {string | number} default + */ +//// [index2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// merge type alias and class (error message improvement needed, see #32368) +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +exports.default = C; +; +/** + * @typedef {string | number} default + */ +//// [index3.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// merge type alias and variable (beharior is borked, see #32366) +var x = 12; +exports.default = x; +/** + * @typedef {string | number} default + */ + + +//// [index1.d.ts] +export type Cls = string | number; +declare class Cls { + static y: string; + x: number; +} +export default Cls; +//// [index2.d.ts] +export default class C { +} +//// [index3.d.ts] +export type _default = string | number; +declare const x: 12; +export { x as default }; diff --git a/tests/baselines/reference/jsDeclarationsDefaultsErr.symbols b/tests/baselines/reference/jsDeclarationsDefaultsErr.symbols new file mode 100644 index 0000000000000..ff8e421fb40d1 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefaultsErr.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/jsdoc/declarations/index1.js === +// merge type alias and alias (should error, see #32367) +class Cls { +>Cls : Symbol(Cls, Decl(index1.js, 0, 0)) + + x = 12; +>x : Symbol(Cls.x, Decl(index1.js, 1, 11)) + + static y = "ok" +>y : Symbol(Cls.y, Decl(index1.js, 2, 11)) +} +export default Cls; +>Cls : Symbol(Cls, Decl(index1.js, 0, 0)) + +/** + * @typedef {string | number} default + */ + +=== tests/cases/conformance/jsdoc/declarations/index2.js === +// merge type alias and class (error message improvement needed, see #32368) +export default class C {}; +>C : Symbol(C, Decl(index2.js, 0, 0)) + +/** + * @typedef {string | number} default + */ + +=== tests/cases/conformance/jsdoc/declarations/index3.js === +// merge type alias and variable (beharior is borked, see #32366) +const x = 12; +>x : Symbol(x, Decl(index3.js, 1, 5)) + +export {x as default}; +>x : Symbol(x, Decl(index3.js, 1, 5)) +>default : Symbol(default, Decl(index3.js, 2, 8), Decl(index3.js, 4, 3)) + +/** + * @typedef {string | number} default + */ + diff --git a/tests/baselines/reference/jsDeclarationsDefaultsErr.types b/tests/baselines/reference/jsDeclarationsDefaultsErr.types new file mode 100644 index 0000000000000..f11382157f5db --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsDefaultsErr.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/jsdoc/declarations/index1.js === +// merge type alias and alias (should error, see #32367) +class Cls { +>Cls : Cls + + x = 12; +>x : number +>12 : 12 + + static y = "ok" +>y : string +>"ok" : "ok" +} +export default Cls; +>Cls : Cls + +/** + * @typedef {string | number} default + */ + +=== tests/cases/conformance/jsdoc/declarations/index2.js === +// merge type alias and class (error message improvement needed, see #32368) +export default class C {}; +>C : C + +/** + * @typedef {string | number} default + */ + +=== tests/cases/conformance/jsdoc/declarations/index3.js === +// merge type alias and variable (beharior is borked, see #32366) +const x = 12; +>x : 12 +>12 : 12 + +export {x as default}; +>x : 12 +>default : 12 + +/** + * @typedef {string | number} default + */ + diff --git a/tests/baselines/reference/jsDeclarationsEnums.errors.txt b/tests/baselines/reference/jsDeclarationsEnums.errors.txt new file mode 100644 index 0000000000000..630d4aab7e9ad --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsEnums.errors.txt @@ -0,0 +1,101 @@ +tests/cases/conformance/jsdoc/declarations/index.js(4,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(6,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(10,6): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(14,6): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(18,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(22,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(24,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(30,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(35,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(41,19): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(47,13): error TS8015: 'enum declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(55,19): error TS8015: 'enum declarations' can only be used in a .ts file. + + +==== tests/cases/conformance/jsdoc/declarations/index.js (12 errors) ==== + // Pretty much all of this should be an error, (since enums are forbidden in js), + // but we should be able to synthesize declarations from the symbols regardless + + export enum A {} + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + + export enum B { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + Member + } + + enum C {} + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + + export { C }; + + enum DD {} + ~~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + + export { DD as D }; + + export enum E {} + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + export { E as EE }; + + export { F as FF }; + export enum F {} + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + + export enum G { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + A = 1, + B, + C + } + + export enum H { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + A = "a", + B = "b" + } + + export enum I { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + A = "a", + B = 0, + C + } + + export const enum J { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + A = 1, + B, + C + } + + export enum K { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, + } + + export const enum L { + ~ +!!! error TS8015: 'enum declarations' can only be used in a .ts file. + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsEnums.js b/tests/baselines/reference/jsDeclarationsEnums.js new file mode 100644 index 0000000000000..1f77223a3541b --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsEnums.js @@ -0,0 +1,170 @@ +//// [index.js] +// Pretty much all of this should be an error, (since enums are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export enum A {} + +export enum B { + Member +} + +enum C {} + +export { C }; + +enum DD {} + +export { DD as D }; + +export enum E {} +export { E as EE }; + +export { F as FF }; +export enum F {} + +export enum G { + A = 1, + B, + C +} + +export enum H { + A = "a", + B = "b" +} + +export enum I { + A = "a", + B = 0, + C +} + +export const enum J { + A = 1, + B, + C +} + +export enum K { + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, +} + +export const enum L { + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, +} + + +//// [index.js] +"use strict"; +// Pretty much all of this should be an error, (since enums are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless +Object.defineProperty(exports, "__esModule", { value: true }); +var A; +(function (A) { +})(A = exports.A || (exports.A = {})); +var B; +(function (B) { + B[B["Member"] = 0] = "Member"; +})(B = exports.B || (exports.B = {})); +var C; +(function (C) { +})(C || (C = {})); +exports.C = C; +var DD; +(function (DD) { +})(DD || (DD = {})); +exports.D = DD; +var E; +(function (E) { +})(E = exports.E || (exports.E = {})); +exports.EE = E; +var F; +(function (F) { +})(F = exports.F || (exports.F = {})); +exports.FF = F; +var G; +(function (G) { + G[G["A"] = 1] = "A"; + G[G["B"] = 2] = "B"; + G[G["C"] = 3] = "C"; +})(G = exports.G || (exports.G = {})); +var H; +(function (H) { + H["A"] = "a"; + H["B"] = "b"; +})(H = exports.H || (exports.H = {})); +var I; +(function (I) { + I["A"] = "a"; + I[I["B"] = 0] = "B"; + I[I["C"] = 1] = "C"; +})(I = exports.I || (exports.I = {})); +var K; +(function (K) { + K[K["None"] = 0] = "None"; + K[K["A"] = 1] = "A"; + K[K["B"] = 2] = "B"; + K[K["C"] = 4] = "C"; + K[K["Mask"] = 7] = "Mask"; +})(K = exports.K || (exports.K = {})); + + +//// [index.d.ts] +export enum A { +} +export enum B { + Member = 0 +} +declare enum C { +} +export { C }; +declare enum DD { +} +export { DD as D }; +export enum E { +} +export { E as EE }; +declare enum F { +} +export { F as FF }; +export enum G { + A = 1, + B = 2, + C = 3 +} +export enum H { + A = "a", + B = "b" +} +export enum I { + A = "a", + B = 0, + C = 1 +} +export const enum J { + A = 1, + B = 2, + C = 3 +} +export enum K { + None = 0, + A = 1, + B = 2, + C = 4, + Mask = 7 +} +export const enum L { + None = 0, + A = 1, + B = 2, + C = 4, + Mask = 7 +} diff --git a/tests/baselines/reference/jsDeclarationsEnums.symbols b/tests/baselines/reference/jsDeclarationsEnums.symbols new file mode 100644 index 0000000000000..7980af3801920 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsEnums.symbols @@ -0,0 +1,134 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since enums are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export enum A {} +>A : Symbol(A, Decl(index.js, 0, 0)) + +export enum B { +>B : Symbol(B, Decl(index.js, 3, 16)) + + Member +>Member : Symbol(B.Member, Decl(index.js, 5, 15)) +} + +enum C {} +>C : Symbol(C, Decl(index.js, 7, 1)) + +export { C }; +>C : Symbol(C, Decl(index.js, 11, 8)) + +enum DD {} +>DD : Symbol(DD, Decl(index.js, 11, 13)) + +export { DD as D }; +>DD : Symbol(DD, Decl(index.js, 11, 13)) +>D : Symbol(D, Decl(index.js, 15, 8)) + +export enum E {} +>E : Symbol(E, Decl(index.js, 15, 19)) + +export { E as EE }; +>E : Symbol(E, Decl(index.js, 15, 19)) +>EE : Symbol(EE, Decl(index.js, 18, 8)) + +export { F as FF }; +>F : Symbol(F, Decl(index.js, 20, 19)) +>FF : Symbol(FF, Decl(index.js, 20, 8)) + +export enum F {} +>F : Symbol(F, Decl(index.js, 20, 19)) + +export enum G { +>G : Symbol(G, Decl(index.js, 21, 16)) + + A = 1, +>A : Symbol(G.A, Decl(index.js, 23, 15)) + + B, +>B : Symbol(G.B, Decl(index.js, 24, 10)) + + C +>C : Symbol(G.C, Decl(index.js, 25, 6)) +} + +export enum H { +>H : Symbol(H, Decl(index.js, 27, 1)) + + A = "a", +>A : Symbol(H.A, Decl(index.js, 29, 15)) + + B = "b" +>B : Symbol(H.B, Decl(index.js, 30, 12)) +} + +export enum I { +>I : Symbol(I, Decl(index.js, 32, 1)) + + A = "a", +>A : Symbol(I.A, Decl(index.js, 34, 15)) + + B = 0, +>B : Symbol(I.B, Decl(index.js, 35, 12)) + + C +>C : Symbol(I.C, Decl(index.js, 36, 10)) +} + +export const enum J { +>J : Symbol(J, Decl(index.js, 38, 1)) + + A = 1, +>A : Symbol(J.A, Decl(index.js, 40, 21)) + + B, +>B : Symbol(J.B, Decl(index.js, 41, 10)) + + C +>C : Symbol(J.C, Decl(index.js, 42, 6)) +} + +export enum K { +>K : Symbol(K, Decl(index.js, 44, 1)) + + None = 0, +>None : Symbol(K.None, Decl(index.js, 46, 15)) + + A = 1 << 0, +>A : Symbol(K.A, Decl(index.js, 47, 15)) + + B = 1 << 1, +>B : Symbol(K.B, Decl(index.js, 48, 15)) + + C = 1 << 2, +>C : Symbol(K.C, Decl(index.js, 49, 15)) + + Mask = A | B | C, +>Mask : Symbol(K.Mask, Decl(index.js, 50, 15)) +>A : Symbol(K.A, Decl(index.js, 47, 15)) +>B : Symbol(K.B, Decl(index.js, 48, 15)) +>C : Symbol(K.C, Decl(index.js, 49, 15)) +} + +export const enum L { +>L : Symbol(L, Decl(index.js, 52, 1)) + + None = 0, +>None : Symbol(L.None, Decl(index.js, 54, 21)) + + A = 1 << 0, +>A : Symbol(L.A, Decl(index.js, 55, 15)) + + B = 1 << 1, +>B : Symbol(L.B, Decl(index.js, 56, 15)) + + C = 1 << 2, +>C : Symbol(L.C, Decl(index.js, 57, 15)) + + Mask = A | B | C, +>Mask : Symbol(L.Mask, Decl(index.js, 58, 15)) +>A : Symbol(L.A, Decl(index.js, 55, 15)) +>B : Symbol(L.B, Decl(index.js, 56, 15)) +>C : Symbol(L.C, Decl(index.js, 57, 15)) +} + diff --git a/tests/baselines/reference/jsDeclarationsEnums.types b/tests/baselines/reference/jsDeclarationsEnums.types new file mode 100644 index 0000000000000..e01b2637fb663 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsEnums.types @@ -0,0 +1,164 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since enums are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export enum A {} +>A : A + +export enum B { +>B : B + + Member +>Member : B.Member +} + +enum C {} +>C : C + +export { C }; +>C : typeof C + +enum DD {} +>DD : DD + +export { DD as D }; +>DD : typeof DD +>D : typeof DD + +export enum E {} +>E : E + +export { E as EE }; +>E : typeof E +>EE : typeof E + +export { F as FF }; +>F : typeof F +>FF : typeof F + +export enum F {} +>F : F + +export enum G { +>G : G + + A = 1, +>A : G.A +>1 : 1 + + B, +>B : G.B + + C +>C : G.C +} + +export enum H { +>H : H + + A = "a", +>A : H.A +>"a" : "a" + + B = "b" +>B : H.B +>"b" : "b" +} + +export enum I { +>I : I + + A = "a", +>A : I.A +>"a" : "a" + + B = 0, +>B : I.B +>0 : 0 + + C +>C : I.C +} + +export const enum J { +>J : J + + A = 1, +>A : J.A +>1 : 1 + + B, +>B : J.B + + C +>C : J.C +} + +export enum K { +>K : K + + None = 0, +>None : K +>0 : 0 + + A = 1 << 0, +>A : K +>1 << 0 : number +>1 : 1 +>0 : 0 + + B = 1 << 1, +>B : K +>1 << 1 : number +>1 : 1 +>1 : 1 + + C = 1 << 2, +>C : K +>1 << 2 : number +>1 : 1 +>2 : 2 + + Mask = A | B | C, +>Mask : K +>A | B | C : number +>A | B : number +>A : K +>B : K +>C : K +} + +export const enum L { +>L : L + + None = 0, +>None : L +>0 : 0 + + A = 1 << 0, +>A : L +>1 << 0 : number +>1 : 1 +>0 : 0 + + B = 1 << 1, +>B : L +>1 << 1 : number +>1 : 1 +>1 : 1 + + C = 1 << 2, +>C : L +>1 << 2 : number +>1 : 1 +>2 : 2 + + Mask = A | B | C, +>Mask : L +>A | B | C : number +>A | B : number +>A : L +>B : L +>C : L +} + diff --git a/tests/baselines/reference/jsDeclarationsFunctions.js b/tests/baselines/reference/jsDeclarationsFunctions.js new file mode 100644 index 0000000000000..2f3adb1960bf6 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctions.js @@ -0,0 +1,157 @@ +//// [index.js] +export function a() {} + +export function b() {} +b.cat = "cat"; + +export function c() {} +c.Cls = class {} + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +export function d(a, b) { return /** @type {*} */(null); } + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +export function e(a, b) { return /** @type {*} */(null); } + +/** + * @template T + * @param {T} a + */ +export function f(a) { + return a; +} +f.self = f; + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function g(a, b) { + return a.x && b.y(); +} + +export { g }; + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} + +export { hh as h }; + +export function i() {} +export { i as ii }; + +export { j as jj }; +export function j() {} + + +//// [index.js] +"use strict"; +exports.__esModule = true; +function a() { } +exports.a = a; +function b() { } +exports.b = b; +b.cat = "cat"; +function c() { } +exports.c = c; +c.Cls = /** @class */ (function () { + function Cls() { + } + return Cls; +}()); +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +function d(a, b) { return /** @type {*} */ (null); } +exports.d = d; +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +function e(a, b) { return /** @type {*} */ (null); } +exports.e = e; +/** + * @template T + * @param {T} a + */ +function f(a) { + return a; +} +exports.f = f; +f.self = f; +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function g(a, b) { + return a.x && b.y(); +} +exports.g = g; +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} +exports.h = hh; +function i() { } +exports.i = i; +exports.ii = i; +function j() { } +exports.j = j; +exports.jj = j; + + +//// [index.d.ts] +export function a(): void; +export function b(): void; +export namespace b { + var cat: string; +} +export function c(): void; +export namespace c { + var Cls: { + new (): {}; + }; +} +export function d(a: number, b: number): string; +export function e(a: T, b: U): T & U; +export function f(a: T): T; +export namespace f { + var self: typeof f; +} +export function i(): void; +export function j(): void; +declare function g(a: { + x: string; +}, b: { + y: typeof b; +}): void; +export { g }; +declare function hh(a: { + x: string; +}, b: { + y: typeof b; +}): void; +export { hh as h }; +export { i as ii }; +export { j as jj }; diff --git a/tests/baselines/reference/jsDeclarationsFunctions.symbols b/tests/baselines/reference/jsDeclarationsFunctions.symbols new file mode 100644 index 0000000000000..0f2a41a6222d8 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctions.symbols @@ -0,0 +1,115 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export function a() {} +>a : Symbol(a, Decl(index.js, 0, 0)) + +export function b() {} +>b : Symbol(b, Decl(index.js, 0, 22), Decl(index.js, 2, 22)) + +b.cat = "cat"; +>b.cat : Symbol(b.cat, Decl(index.js, 2, 22)) +>b : Symbol(b, Decl(index.js, 0, 22), Decl(index.js, 2, 22)) +>cat : Symbol(b.cat, Decl(index.js, 2, 22)) + +export function c() {} +>c : Symbol(c, Decl(index.js, 3, 14), Decl(index.js, 5, 22)) + +c.Cls = class {} +>c.Cls : Symbol(c.Cls, Decl(index.js, 5, 22)) +>c : Symbol(c, Decl(index.js, 3, 14), Decl(index.js, 5, 22)) +>Cls : Symbol(c.Cls, Decl(index.js, 5, 22)) + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +export function d(a, b) { return /** @type {*} */(null); } +>d : Symbol(d, Decl(index.js, 6, 16)) +>a : Symbol(a, Decl(index.js, 13, 18)) +>b : Symbol(b, Decl(index.js, 13, 20)) + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +export function e(a, b) { return /** @type {*} */(null); } +>e : Symbol(e, Decl(index.js, 13, 58)) +>a : Symbol(a, Decl(index.js, 21, 18)) +>b : Symbol(b, Decl(index.js, 21, 20)) + +/** + * @template T + * @param {T} a + */ +export function f(a) { +>f : Symbol(f, Decl(index.js, 21, 58), Decl(index.js, 29, 1)) +>a : Symbol(a, Decl(index.js, 27, 18)) + + return a; +>a : Symbol(a, Decl(index.js, 27, 18)) +} +f.self = f; +>f.self : Symbol(f.self, Decl(index.js, 29, 1)) +>f : Symbol(f, Decl(index.js, 21, 58), Decl(index.js, 29, 1)) +>self : Symbol(f.self, Decl(index.js, 29, 1)) +>f : Symbol(f, Decl(index.js, 21, 58), Decl(index.js, 29, 1)) + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function g(a, b) { +>g : Symbol(g, Decl(index.js, 30, 11)) +>a : Symbol(a, Decl(index.js, 36, 11)) +>b : Symbol(b, Decl(index.js, 36, 13)) + + return a.x && b.y(); +>a.x : Symbol(x, Decl(index.js, 33, 12)) +>a : Symbol(a, Decl(index.js, 36, 11)) +>x : Symbol(x, Decl(index.js, 33, 12)) +>b.y : Symbol(y, Decl(index.js, 34, 12)) +>b : Symbol(b, Decl(index.js, 36, 13)) +>y : Symbol(y, Decl(index.js, 34, 12)) +} + +export { g }; +>g : Symbol(g, Decl(index.js, 40, 8)) + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function hh(a, b) { +>hh : Symbol(hh, Decl(index.js, 40, 13)) +>a : Symbol(a, Decl(index.js, 46, 12)) +>b : Symbol(b, Decl(index.js, 46, 14)) + + return a.x && b.y(); +>a.x : Symbol(x, Decl(index.js, 43, 12)) +>a : Symbol(a, Decl(index.js, 46, 12)) +>x : Symbol(x, Decl(index.js, 43, 12)) +>b.y : Symbol(y, Decl(index.js, 44, 12)) +>b : Symbol(b, Decl(index.js, 46, 14)) +>y : Symbol(y, Decl(index.js, 44, 12)) +} + +export { hh as h }; +>hh : Symbol(hh, Decl(index.js, 40, 13)) +>h : Symbol(h, Decl(index.js, 50, 8)) + +export function i() {} +>i : Symbol(i, Decl(index.js, 50, 19)) + +export { i as ii }; +>i : Symbol(i, Decl(index.js, 50, 19)) +>ii : Symbol(ii, Decl(index.js, 53, 8)) + +export { j as jj }; +>j : Symbol(j, Decl(index.js, 55, 19)) +>jj : Symbol(jj, Decl(index.js, 55, 8)) + +export function j() {} +>j : Symbol(j, Decl(index.js, 55, 19)) + diff --git a/tests/baselines/reference/jsDeclarationsFunctions.types b/tests/baselines/reference/jsDeclarationsFunctions.types new file mode 100644 index 0000000000000..72d67885c2d61 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctions.types @@ -0,0 +1,128 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export function a() {} +>a : () => void + +export function b() {} +>b : typeof b + +b.cat = "cat"; +>b.cat = "cat" : "cat" +>b.cat : string +>b : typeof b +>cat : string +>"cat" : "cat" + +export function c() {} +>c : typeof c + +c.Cls = class {} +>c.Cls = class {} : typeof Cls +>c.Cls : typeof Cls +>c : typeof c +>Cls : typeof Cls +>class {} : typeof Cls + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +export function d(a, b) { return /** @type {*} */(null); } +>d : (a: number, b: number) => string +>a : number +>b : number +>(null) : any +>null : null + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +export function e(a, b) { return /** @type {*} */(null); } +>e : (a: T, b: U) => T & U +>a : T +>b : U +>(null) : any +>null : null + +/** + * @template T + * @param {T} a + */ +export function f(a) { +>f : typeof f +>a : T + + return a; +>a : T +} +f.self = f; +>f.self = f : typeof f +>f.self : typeof f +>f : typeof f +>self : typeof f +>f : typeof f + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function g(a, b) { +>g : (a: { x: string; }, b: { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; }) => void +>a : { x: string; } +>b : { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; } + + return a.x && b.y(); +>a.x && b.y() : void +>a.x : string +>a : { x: string; } +>x : string +>b.y() : void +>b.y : typeof import("tests/cases/conformance/jsdoc/declarations/index").b +>b : { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; } +>y : typeof import("tests/cases/conformance/jsdoc/declarations/index").b +} + +export { g }; +>g : (a: { x: string; }, b: { y: typeof b; }) => void + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function hh(a, b) { +>hh : (a: { x: string; }, b: { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; }) => void +>a : { x: string; } +>b : { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; } + + return a.x && b.y(); +>a.x && b.y() : void +>a.x : string +>a : { x: string; } +>x : string +>b.y() : void +>b.y : typeof import("tests/cases/conformance/jsdoc/declarations/index").b +>b : { y: typeof import("tests/cases/conformance/jsdoc/declarations/index").b; } +>y : typeof import("tests/cases/conformance/jsdoc/declarations/index").b +} + +export { hh as h }; +>hh : (a: { x: string; }, b: { y: typeof b; }) => void +>h : (a: { x: string; }, b: { y: typeof b; }) => void + +export function i() {} +>i : () => void + +export { i as ii }; +>i : () => void +>ii : () => void + +export { j as jj }; +>j : () => void +>jj : () => void + +export function j() {} +>j : () => void + diff --git a/tests/baselines/reference/jsDeclarationsFunctionsCjs.js b/tests/baselines/reference/jsDeclarationsFunctionsCjs.js new file mode 100644 index 0000000000000..d4abe1c24a59f --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctionsCjs.js @@ -0,0 +1,167 @@ +//// [index.js] +module.exports.a = function a() {} + +module.exports.b = function b() {} +module.exports.b.cat = "cat"; + +module.exports.c = function c() {} +module.exports.c.Cls = class {} + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +module.exports.d = function d(a, b) { return /** @type {*} */(null); } + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +module.exports.e = function e(a, b) { return /** @type {*} */(null); } + +/** + * @template T + * @param {T} a + */ +module.exports.f = function f(a) { + return a; +} +module.exports.f.self = module.exports.f; + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function g(a, b) { + return a.x && b.y(); +} + +module.exports.g = g; + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} + +module.exports.h = hh; + +module.exports.i = function i() {} +module.exports.ii = module.exports.i; + +// note that this last one doesn't make much sense in cjs, since exports aren't hoisted bindings +module.exports.jj = module.exports.j; +module.exports.j = function j() {} + + +//// [index.js] +module.exports.a = function a() { }; +module.exports.b = function b() { }; +module.exports.b.cat = "cat"; +module.exports.c = function c() { }; +module.exports.c.Cls = /** @class */ (function () { + function Cls() { + } + return Cls; +}()); +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +module.exports.d = function d(a, b) { return /** @type {*} */ (null); }; +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +module.exports.e = function e(a, b) { return /** @type {*} */ (null); }; +/** + * @template T + * @param {T} a + */ +module.exports.f = function f(a) { + return a; +}; +module.exports.f.self = module.exports.f; +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function g(a, b) { + return a.x && b.y(); +} +module.exports.g = g; +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} +module.exports.h = hh; +module.exports.i = function i() { }; +module.exports.ii = module.exports.i; +// note that this last one doesn't make much sense in cjs, since exports aren't hoisted bindings +module.exports.jj = module.exports.j; +module.exports.j = function j() { }; + + +//// [index.d.ts] +declare var a_1: () => void; +export { a_1 as a }; +declare var b_1: { + (): void; + cat: string; +}; +export { b_1 as b }; +declare var c_1: { + (): void; + Cls: { + new (): {}; + }; +}; +export { c_1 as c }; +declare var d_1: (a: number, b: number) => string; +export { d_1 as d }; +declare var e_1: (a: T, b: U) => T & U; +export { e_1 as e }; +declare var f_1: { + (a: T): T; + self: any; +}; +export { f_1 as f }; +declare function g(a: { + x: string; +}, b: { + y: { + (): void; + cat: string; + }; +}): void; +declare var g_1: typeof g; +export { g_1 as g }; +declare function hh(a: { + x: string; +}, b: { + y: { + (): void; + cat: string; + }; +}): void; +declare var h_1: typeof hh; +export { h_1 as h }; +declare var i_1: () => void; +export { i_1 as i }; +declare var ii_1: () => void; +export { ii_1 as ii }; +declare var jj_1: () => void; +export { jj_1 as jj }; +declare var j_1: () => void; +export { j_1 as j }; diff --git a/tests/baselines/reference/jsDeclarationsFunctionsCjs.symbols b/tests/baselines/reference/jsDeclarationsFunctionsCjs.symbols new file mode 100644 index 0000000000000..b900de3c1f076 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctionsCjs.symbols @@ -0,0 +1,197 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +module.exports.a = function a() {} +>module.exports.a : Symbol(a, Decl(index.js, 0, 0)) +>module.exports : Symbol(a, Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>a : Symbol(a, Decl(index.js, 0, 0)) +>a : Symbol(a, Decl(index.js, 0, 18)) + +module.exports.b = function b() {} +>module.exports.b : Symbol(b, Decl(index.js, 0, 34), Decl(index.js, 3, 15)) +>module.exports : Symbol(b, Decl(index.js, 0, 34), Decl(index.js, 3, 15)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>b : Symbol(b, Decl(index.js, 0, 34), Decl(index.js, 3, 15)) +>b : Symbol(b, Decl(index.js, 2, 18)) + +module.exports.b.cat = "cat"; +>module.exports.b.cat : Symbol(b.cat, Decl(index.js, 2, 34)) +>module.exports.b : Symbol(b.cat, Decl(index.js, 2, 34)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>b : Symbol(b, Decl(index.js, 0, 34), Decl(index.js, 3, 15)) +>cat : Symbol(b.cat, Decl(index.js, 2, 34)) + +module.exports.c = function c() {} +>module.exports.c : Symbol(c, Decl(index.js, 3, 29), Decl(index.js, 6, 15)) +>module.exports : Symbol(c, Decl(index.js, 3, 29), Decl(index.js, 6, 15)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>c : Symbol(c, Decl(index.js, 3, 29), Decl(index.js, 6, 15)) +>c : Symbol(c, Decl(index.js, 5, 18)) + +module.exports.c.Cls = class {} +>module.exports.c.Cls : Symbol(c.Cls, Decl(index.js, 5, 34)) +>module.exports.c : Symbol(c.Cls, Decl(index.js, 5, 34)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>c : Symbol(c, Decl(index.js, 3, 29), Decl(index.js, 6, 15)) +>Cls : Symbol(c.Cls, Decl(index.js, 5, 34)) + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +module.exports.d = function d(a, b) { return /** @type {*} */(null); } +>module.exports.d : Symbol(d, Decl(index.js, 6, 31)) +>module.exports : Symbol(d, Decl(index.js, 6, 31)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>d : Symbol(d, Decl(index.js, 6, 31)) +>d : Symbol(d, Decl(index.js, 13, 18)) +>a : Symbol(a, Decl(index.js, 13, 30)) +>b : Symbol(b, Decl(index.js, 13, 32)) + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +module.exports.e = function e(a, b) { return /** @type {*} */(null); } +>module.exports.e : Symbol(e, Decl(index.js, 13, 70)) +>module.exports : Symbol(e, Decl(index.js, 13, 70)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>e : Symbol(e, Decl(index.js, 13, 70)) +>e : Symbol(e, Decl(index.js, 21, 18)) +>a : Symbol(a, Decl(index.js, 21, 30)) +>b : Symbol(b, Decl(index.js, 21, 32)) + +/** + * @template T + * @param {T} a + */ +module.exports.f = function f(a) { +>module.exports.f : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) +>module.exports : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>f : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) +>f : Symbol(f, Decl(index.js, 27, 18)) +>a : Symbol(a, Decl(index.js, 27, 30)) + + return a; +>a : Symbol(a, Decl(index.js, 27, 30)) +} +module.exports.f.self = module.exports.f; +>module.exports.f.self : Symbol(f.self, Decl(index.js, 29, 1)) +>module.exports.f : Symbol(f.self, Decl(index.js, 29, 1)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>f : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) +>self : Symbol(f.self, Decl(index.js, 29, 1)) +>module.exports.f : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>f : Symbol(f, Decl(index.js, 21, 70), Decl(index.js, 30, 15)) + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function g(a, b) { +>g : Symbol(g, Decl(index.js, 30, 41)) +>a : Symbol(a, Decl(index.js, 36, 11)) +>b : Symbol(b, Decl(index.js, 36, 13)) + + return a.x && b.y(); +>a.x : Symbol(x, Decl(index.js, 33, 12)) +>a : Symbol(a, Decl(index.js, 36, 11)) +>x : Symbol(x, Decl(index.js, 33, 12)) +>b.y : Symbol(y, Decl(index.js, 34, 12)) +>b : Symbol(b, Decl(index.js, 36, 13)) +>y : Symbol(y, Decl(index.js, 34, 12)) +} + +module.exports.g = g; +>module.exports.g : Symbol(g, Decl(index.js, 38, 1)) +>module.exports : Symbol(g, Decl(index.js, 38, 1)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>g : Symbol(g, Decl(index.js, 38, 1)) +>g : Symbol(g, Decl(index.js, 30, 41)) + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function hh(a, b) { +>hh : Symbol(hh, Decl(index.js, 40, 21)) +>a : Symbol(a, Decl(index.js, 46, 12)) +>b : Symbol(b, Decl(index.js, 46, 14)) + + return a.x && b.y(); +>a.x : Symbol(x, Decl(index.js, 43, 12)) +>a : Symbol(a, Decl(index.js, 46, 12)) +>x : Symbol(x, Decl(index.js, 43, 12)) +>b.y : Symbol(y, Decl(index.js, 44, 12)) +>b : Symbol(b, Decl(index.js, 46, 14)) +>y : Symbol(y, Decl(index.js, 44, 12)) +} + +module.exports.h = hh; +>module.exports.h : Symbol(h, Decl(index.js, 48, 1)) +>module.exports : Symbol(h, Decl(index.js, 48, 1)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>h : Symbol(h, Decl(index.js, 48, 1)) +>hh : Symbol(hh, Decl(index.js, 40, 21)) + +module.exports.i = function i() {} +>module.exports.i : Symbol(i, Decl(index.js, 50, 22)) +>module.exports : Symbol(i, Decl(index.js, 50, 22)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>i : Symbol(i, Decl(index.js, 50, 22)) +>i : Symbol(i, Decl(index.js, 52, 18)) + +module.exports.ii = module.exports.i; +>module.exports.ii : Symbol(ii, Decl(index.js, 52, 34)) +>module.exports : Symbol(ii, Decl(index.js, 52, 34)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>ii : Symbol(ii, Decl(index.js, 52, 34)) +>module.exports.i : Symbol(i, Decl(index.js, 50, 22)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>i : Symbol(i, Decl(index.js, 50, 22)) + +// note that this last one doesn't make much sense in cjs, since exports aren't hoisted bindings +module.exports.jj = module.exports.j; +>module.exports.jj : Symbol(jj, Decl(index.js, 53, 37)) +>module.exports : Symbol(jj, Decl(index.js, 53, 37)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>jj : Symbol(jj, Decl(index.js, 53, 37)) +>module.exports.j : Symbol(j, Decl(index.js, 56, 37)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>j : Symbol(j, Decl(index.js, 56, 37)) + +module.exports.j = function j() {} +>module.exports.j : Symbol(j, Decl(index.js, 56, 37)) +>module.exports : Symbol(j, Decl(index.js, 56, 37)) +>module : Symbol(module, Decl(index.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>j : Symbol(j, Decl(index.js, 56, 37)) +>j : Symbol(j, Decl(index.js, 57, 18)) + diff --git a/tests/baselines/reference/jsDeclarationsFunctionsCjs.types b/tests/baselines/reference/jsDeclarationsFunctionsCjs.types new file mode 100644 index 0000000000000..ec6843764ff39 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsFunctionsCjs.types @@ -0,0 +1,230 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +module.exports.a = function a() {} +>module.exports.a = function a() {} : () => void +>module.exports.a : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>a : () => void +>function a() {} : () => void +>a : () => void + +module.exports.b = function b() {} +>module.exports.b = function b() {} : { (): void; cat: string; } +>module.exports.b : { (): void; cat: string; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>b : { (): void; cat: string; } +>function b() {} : { (): void; cat: string; } +>b : { (): void; cat: string; } + +module.exports.b.cat = "cat"; +>module.exports.b.cat = "cat" : "cat" +>module.exports.b.cat : string +>module.exports.b : { (): void; cat: string; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>b : { (): void; cat: string; } +>cat : string +>"cat" : "cat" + +module.exports.c = function c() {} +>module.exports.c = function c() {} : { (): void; Cls: typeof Cls; } +>module.exports.c : { (): void; Cls: typeof Cls; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>c : { (): void; Cls: typeof Cls; } +>function c() {} : { (): void; Cls: typeof Cls; } +>c : { (): void; Cls: typeof Cls; } + +module.exports.c.Cls = class {} +>module.exports.c.Cls = class {} : typeof Cls +>module.exports.c.Cls : typeof Cls +>module.exports.c : { (): void; Cls: typeof Cls; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>c : { (): void; Cls: typeof Cls; } +>Cls : typeof Cls +>class {} : typeof Cls + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +module.exports.d = function d(a, b) { return /** @type {*} */(null); } +>module.exports.d = function d(a, b) { return /** @type {*} */(null); } : (a: number, b: number) => string +>module.exports.d : (a: number, b: number) => string +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>d : (a: number, b: number) => string +>function d(a, b) { return /** @type {*} */(null); } : (a: number, b: number) => string +>d : (a: number, b: number) => string +>a : number +>b : number +>(null) : any +>null : null + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +module.exports.e = function e(a, b) { return /** @type {*} */(null); } +>module.exports.e = function e(a, b) { return /** @type {*} */(null); } : (a: T, b: U) => T & U +>module.exports.e : (a: T, b: U) => T & U +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>e : (a: T, b: U) => T & U +>function e(a, b) { return /** @type {*} */(null); } : (a: T, b: U) => T & U +>e : (a: T, b: U) => T & U +>a : T +>b : U +>(null) : any +>null : null + +/** + * @template T + * @param {T} a + */ +module.exports.f = function f(a) { +>module.exports.f = function f(a) { return a;} : { (a: T): T; self: any; } +>module.exports.f : { (a: T): T; self: any; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>f : { (a: T): T; self: any; } +>function f(a) { return a;} : { (a: T): T; self: any; } +>f : { (a: T): T; self: any; } +>a : T + + return a; +>a : T +} +module.exports.f.self = module.exports.f; +>module.exports.f.self = module.exports.f : { (a: T): T; self: any; } +>module.exports.f.self : { (a: T): T; self: any; } +>module.exports.f : { (a: T): T; self: any; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>f : { (a: T): T; self: any; } +>self : { (a: T): T; self: any; } +>module.exports.f : { (a: T): T; self: any; } +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>f : { (a: T): T; self: any; } + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function g(a, b) { +>g : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>a : { x: string; } +>b : { y: { (): void; cat: string; }; } + + return a.x && b.y(); +>a.x && b.y() : void +>a.x : string +>a : { x: string; } +>x : string +>b.y() : void +>b.y : { (): void; cat: string; } +>b : { y: { (): void; cat: string; }; } +>y : { (): void; cat: string; } +} + +module.exports.g = g; +>module.exports.g = g : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>module.exports.g : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>g : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>g : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function hh(a, b) { +>hh : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>a : { x: string; } +>b : { y: { (): void; cat: string; }; } + + return a.x && b.y(); +>a.x && b.y() : void +>a.x : string +>a : { x: string; } +>x : string +>b.y() : void +>b.y : { (): void; cat: string; } +>b : { y: { (): void; cat: string; }; } +>y : { (): void; cat: string; } +} + +module.exports.h = hh; +>module.exports.h = hh : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>module.exports.h : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>h : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void +>hh : (a: { x: string; }, b: { y: { (): void; cat: string; }; }) => void + +module.exports.i = function i() {} +>module.exports.i = function i() {} : () => void +>module.exports.i : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>i : () => void +>function i() {} : () => void +>i : () => void + +module.exports.ii = module.exports.i; +>module.exports.ii = module.exports.i : () => void +>module.exports.ii : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>ii : () => void +>module.exports.i : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>i : () => void + +// note that this last one doesn't make much sense in cjs, since exports aren't hoisted bindings +module.exports.jj = module.exports.j; +>module.exports.jj = module.exports.j : () => void +>module.exports.jj : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>jj : () => void +>module.exports.j : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>j : () => void + +module.exports.j = function j() {} +>module.exports.j = function j() {} : () => void +>module.exports.j : () => void +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>module : { "tests/cases/conformance/jsdoc/declarations/index": typeof import("tests/cases/conformance/jsdoc/declarations/index"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/index") +>j : () => void +>function j() {} : () => void +>j : () => void + diff --git a/tests/baselines/reference/jsDeclarationsInterfaces.errors.txt b/tests/baselines/reference/jsDeclarationsInterfaces.errors.txt new file mode 100644 index 0000000000000..24ed71af90837 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsInterfaces.errors.txt @@ -0,0 +1,200 @@ +tests/cases/conformance/jsdoc/declarations/index.js(4,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(6,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(10,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(31,11): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(35,11): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(39,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(43,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(45,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(49,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(53,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(57,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(61,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(65,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(67,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(71,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(75,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(80,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(84,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(87,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(91,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(95,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(100,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(105,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(107,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(111,18): error TS8006: 'interface declarations' can only be used in a .ts file. +tests/cases/conformance/jsdoc/declarations/index.js(115,18): error TS8006: 'interface declarations' can only be used in a .ts file. + + +==== tests/cases/conformance/jsdoc/declarations/index.js (26 errors) ==== + // Pretty much all of this should be an error, (since interfaces are forbidden in js), + // but we should be able to synthesize declarations from the symbols regardless + + export interface A {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export interface B { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + cat: string; + } + + export interface C { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + field: T & U; + optionalField?: T; + readonly readonlyField: T & U; + readonly readonlyOptionalField?: U; + (): number; + (x: T): U; + (x: Q): T & Q; + + new (): string; + new (x: T): U; + new (x: Q): T & Q; + + method(): number; + method(a: T & Q): Q & number; + method(a?: number): number; + method(...args: any[]): number; + + optMethod?(): number; + } + + interface G {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export { G }; + + interface HH {} + ~~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export { HH as H }; + + export interface I {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + export { I as II }; + + export { J as JJ }; + export interface J {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export interface K extends I,J { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + x: string; + } + + export interface L extends K { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + y: string; + } + + export interface M { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + field: T; + } + + export interface N extends M { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + other: U; + } + + export interface O { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: string; + } + + export interface P extends O {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export interface Q extends O { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: "ok"; + } + + export interface R extends O { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: number]: "ok"; + } + + export interface S extends O { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: "ok"; + [idx: number]: never; + } + + export interface T { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: number]: string; + } + + export interface U extends T {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + + export interface V extends T { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: string; + } + + export interface W extends T { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: number]: "ok"; + } + + export interface X extends T { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: string; + [idx: number]: "ok"; + } + + export interface Y { + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: {x: number}; + [idx: number]: {x: number, y: number}; + } + + export interface Z extends Y {} + ~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + + export interface AA extends Y { + ~~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: {x: number, y: number}; + } + + export interface BB extends Y { + ~~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: number]: {x: 0, y: 0}; + } + + export interface CC extends Y { + ~~ +!!! error TS8006: 'interface declarations' can only be used in a .ts file. + [idx: string]: {x: number, y: number}; + [idx: number]: {x: 0, y: 0}; + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsInterfaces.js b/tests/baselines/reference/jsDeclarationsInterfaces.js new file mode 100644 index 0000000000000..c3180f3fe8030 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsInterfaces.js @@ -0,0 +1,238 @@ +//// [index.js] +// Pretty much all of this should be an error, (since interfaces are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export interface A {} + +export interface B { + cat: string; +} + +export interface C { + field: T & U; + optionalField?: T; + readonly readonlyField: T & U; + readonly readonlyOptionalField?: U; + (): number; + (x: T): U; + (x: Q): T & Q; + + new (): string; + new (x: T): U; + new (x: Q): T & Q; + + method(): number; + method(a: T & Q): Q & number; + method(a?: number): number; + method(...args: any[]): number; + + optMethod?(): number; +} + +interface G {} + +export { G }; + +interface HH {} + +export { HH as H }; + +export interface I {} +export { I as II }; + +export { J as JJ }; +export interface J {} + +export interface K extends I,J { + x: string; +} + +export interface L extends K { + y: string; +} + +export interface M { + field: T; +} + +export interface N extends M { + other: U; +} + +export interface O { + [idx: string]: string; +} + +export interface P extends O {} + +export interface Q extends O { + [idx: string]: "ok"; +} + +export interface R extends O { + [idx: number]: "ok"; +} + +export interface S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} + +export interface T { + [idx: number]: string; +} + +export interface U extends T {} + + +export interface V extends T { + [idx: string]: string; +} + +export interface W extends T { + [idx: number]: "ok"; +} + +export interface X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} + +export interface Y { + [idx: string]: {x: number}; + [idx: number]: {x: number, y: number}; +} + +export interface Z extends Y {} + +export interface AA extends Y { + [idx: string]: {x: number, y: number}; +} + +export interface BB extends Y { + [idx: number]: {x: 0, y: 0}; +} + +export interface CC extends Y { + [idx: string]: {x: number, y: number}; + [idx: number]: {x: 0, y: 0}; +} + + +//// [index.js] +"use strict"; +// Pretty much all of this should be an error, (since interfaces are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless +Object.defineProperty(exports, "__esModule", { value: true }); + + +//// [index.d.ts] +export interface A { +} +export interface B { + cat: string; +} +export interface C { + new (): string; + new (x: T_1): U_1; + new (x: Q_4): T_1 & Q_4; + (): number; + (x: T_1): U_1; + (x: Q_3): T_1 & Q_3; + field: T_1 & U_1; + optionalField?: T_1; + readonly readonlyField: T_1 & U_1; + readonly readonlyOptionalField?: U_1; + method(): number; + method(a: T_1 & Q_2): Q_2 & number; + method(a?: number): number; + method(...args: any[]): number; + optMethod?(): number; +} +interface G { +} +export { G }; +interface HH { +} +export { HH as H }; +export interface I { +} +export { I as II }; +interface J { +} +export { J as JJ }; +export interface K extends I, J { + x: string; +} +export interface L extends K { + y: string; +} +export interface M { + field: T_1; +} +export interface N extends M { + other: U_1; +} +export interface O { + [idx: string]: string; +} +export interface P extends O { +} +export interface Q extends O { + [idx: string]: "ok"; +} +export interface R extends O { + [idx: number]: "ok"; +} +export interface S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} +export interface T { + [idx: number]: string; +} +export interface U extends T { +} +export interface V extends T { + [idx: string]: string; +} +export interface W extends T { + [idx: number]: "ok"; +} +export interface X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} +export interface Y { + [idx: string]: { + x: number; + }; + [idx: number]: { + x: number; + y: number; + }; +} +export interface Z extends Y { +} +export interface AA extends Y { + [idx: string]: { + x: number; + y: number; + }; +} +export interface BB extends Y { + [idx: number]: { + x: 0; + y: 0; + }; +} +export interface CC extends Y { + [idx: string]: { + x: number; + y: number; + }; + [idx: number]: { + x: 0; + y: 0; + }; +} diff --git a/tests/baselines/reference/jsDeclarationsInterfaces.symbols b/tests/baselines/reference/jsDeclarationsInterfaces.symbols new file mode 100644 index 0000000000000..d042802f42229 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsInterfaces.symbols @@ -0,0 +1,280 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since interfaces are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export interface A {} +>A : Symbol(A, Decl(index.js, 0, 0)) + +export interface B { +>B : Symbol(B, Decl(index.js, 3, 21)) + + cat: string; +>cat : Symbol(B.cat, Decl(index.js, 5, 20)) +} + +export interface C { +>C : Symbol(C, Decl(index.js, 7, 1)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + field: T & U; +>field : Symbol(C.field, Decl(index.js, 9, 26)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + optionalField?: T; +>optionalField : Symbol(C.optionalField, Decl(index.js, 10, 17)) +>T : Symbol(T, Decl(index.js, 9, 19)) + + readonly readonlyField: T & U; +>readonlyField : Symbol(C.readonlyField, Decl(index.js, 11, 22)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + readonly readonlyOptionalField?: U; +>readonlyOptionalField : Symbol(C.readonlyOptionalField, Decl(index.js, 12, 34)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + (): number; + (x: T): U; +>x : Symbol(x, Decl(index.js, 15, 5)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + (x: Q): T & Q; +>Q : Symbol(Q, Decl(index.js, 16, 5)) +>x : Symbol(x, Decl(index.js, 16, 8)) +>Q : Symbol(Q, Decl(index.js, 16, 5)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>Q : Symbol(Q, Decl(index.js, 16, 5)) + + new (): string; + new (x: T): U; +>x : Symbol(x, Decl(index.js, 19, 9)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>U : Symbol(U, Decl(index.js, 9, 21)) + + new (x: Q): T & Q; +>Q : Symbol(Q, Decl(index.js, 20, 9)) +>x : Symbol(x, Decl(index.js, 20, 12)) +>Q : Symbol(Q, Decl(index.js, 20, 9)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>Q : Symbol(Q, Decl(index.js, 20, 9)) + + method(): number; +>method : Symbol(C.method, Decl(index.js, 20, 25), Decl(index.js, 22, 33), Decl(index.js, 23, 36), Decl(index.js, 24, 31)) +>Q : Symbol(Q, Decl(index.js, 22, 11)) + + method(a: T & Q): Q & number; +>method : Symbol(C.method, Decl(index.js, 20, 25), Decl(index.js, 22, 33), Decl(index.js, 23, 36), Decl(index.js, 24, 31)) +>Q : Symbol(Q, Decl(index.js, 23, 11)) +>a : Symbol(a, Decl(index.js, 23, 14)) +>T : Symbol(T, Decl(index.js, 9, 19)) +>Q : Symbol(Q, Decl(index.js, 23, 11)) +>Q : Symbol(Q, Decl(index.js, 23, 11)) + + method(a?: number): number; +>method : Symbol(C.method, Decl(index.js, 20, 25), Decl(index.js, 22, 33), Decl(index.js, 23, 36), Decl(index.js, 24, 31)) +>a : Symbol(a, Decl(index.js, 24, 11)) + + method(...args: any[]): number; +>method : Symbol(C.method, Decl(index.js, 20, 25), Decl(index.js, 22, 33), Decl(index.js, 23, 36), Decl(index.js, 24, 31)) +>args : Symbol(args, Decl(index.js, 25, 11)) + + optMethod?(): number; +>optMethod : Symbol(C.optMethod, Decl(index.js, 25, 35)) +} + +interface G {} +>G : Symbol(G, Decl(index.js, 28, 1)) + +export { G }; +>G : Symbol(G, Decl(index.js, 32, 8)) + +interface HH {} +>HH : Symbol(HH, Decl(index.js, 32, 13)) + +export { HH as H }; +>HH : Symbol(HH, Decl(index.js, 32, 13)) +>H : Symbol(H, Decl(index.js, 36, 8)) + +export interface I {} +>I : Symbol(I, Decl(index.js, 36, 19)) + +export { I as II }; +>I : Symbol(I, Decl(index.js, 36, 19)) +>II : Symbol(II, Decl(index.js, 39, 8)) + +export { J as JJ }; +>J : Symbol(J, Decl(index.js, 41, 19)) +>JJ : Symbol(JJ, Decl(index.js, 41, 8)) + +export interface J {} +>J : Symbol(J, Decl(index.js, 41, 19)) + +export interface K extends I,J { +>K : Symbol(K, Decl(index.js, 42, 21)) +>I : Symbol(I, Decl(index.js, 36, 19)) +>J : Symbol(J, Decl(index.js, 41, 19)) + + x: string; +>x : Symbol(K.x, Decl(index.js, 44, 32)) +} + +export interface L extends K { +>L : Symbol(L, Decl(index.js, 46, 1)) +>K : Symbol(K, Decl(index.js, 42, 21)) + + y: string; +>y : Symbol(L.y, Decl(index.js, 48, 30)) +} + +export interface M { +>M : Symbol(M, Decl(index.js, 50, 1)) +>T : Symbol(T, Decl(index.js, 52, 19)) + + field: T; +>field : Symbol(M.field, Decl(index.js, 52, 23)) +>T : Symbol(T, Decl(index.js, 52, 19)) +} + +export interface N extends M { +>N : Symbol(N, Decl(index.js, 54, 1)) +>U : Symbol(U, Decl(index.js, 56, 19)) +>M : Symbol(M, Decl(index.js, 50, 1)) +>U : Symbol(U, Decl(index.js, 56, 19)) + + other: U; +>other : Symbol(N.other, Decl(index.js, 56, 36)) +>U : Symbol(U, Decl(index.js, 56, 19)) +} + +export interface O { +>O : Symbol(O, Decl(index.js, 58, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 61, 5)) +} + +export interface P extends O {} +>P : Symbol(P, Decl(index.js, 62, 1)) +>O : Symbol(O, Decl(index.js, 58, 1)) + +export interface Q extends O { +>Q : Symbol(Q, Decl(index.js, 64, 31)) +>O : Symbol(O, Decl(index.js, 58, 1)) + + [idx: string]: "ok"; +>idx : Symbol(idx, Decl(index.js, 67, 5)) +} + +export interface R extends O { +>R : Symbol(R, Decl(index.js, 68, 1)) +>O : Symbol(O, Decl(index.js, 58, 1)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 71, 5)) +} + +export interface S extends O { +>S : Symbol(S, Decl(index.js, 72, 1)) +>O : Symbol(O, Decl(index.js, 58, 1)) + + [idx: string]: "ok"; +>idx : Symbol(idx, Decl(index.js, 75, 5)) + + [idx: number]: never; +>idx : Symbol(idx, Decl(index.js, 76, 5)) +} + +export interface T { +>T : Symbol(T, Decl(index.js, 77, 1)) + + [idx: number]: string; +>idx : Symbol(idx, Decl(index.js, 80, 5)) +} + +export interface U extends T {} +>U : Symbol(U, Decl(index.js, 81, 1)) +>T : Symbol(T, Decl(index.js, 77, 1)) + + +export interface V extends T { +>V : Symbol(V, Decl(index.js, 83, 31)) +>T : Symbol(T, Decl(index.js, 77, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 87, 5)) +} + +export interface W extends T { +>W : Symbol(W, Decl(index.js, 88, 1)) +>T : Symbol(T, Decl(index.js, 77, 1)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 91, 5)) +} + +export interface X extends T { +>X : Symbol(X, Decl(index.js, 92, 1)) +>T : Symbol(T, Decl(index.js, 77, 1)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(index.js, 95, 5)) + + [idx: number]: "ok"; +>idx : Symbol(idx, Decl(index.js, 96, 5)) +} + +export interface Y { +>Y : Symbol(Y, Decl(index.js, 97, 1)) + + [idx: string]: {x: number}; +>idx : Symbol(idx, Decl(index.js, 100, 5)) +>x : Symbol(x, Decl(index.js, 100, 20)) + + [idx: number]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 101, 5)) +>x : Symbol(x, Decl(index.js, 101, 20)) +>y : Symbol(y, Decl(index.js, 101, 30)) +} + +export interface Z extends Y {} +>Z : Symbol(Z, Decl(index.js, 102, 1)) +>Y : Symbol(Y, Decl(index.js, 97, 1)) + +export interface AA extends Y { +>AA : Symbol(AA, Decl(index.js, 104, 31)) +>Y : Symbol(Y, Decl(index.js, 97, 1)) + + [idx: string]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 107, 5)) +>x : Symbol(x, Decl(index.js, 107, 20)) +>y : Symbol(y, Decl(index.js, 107, 30)) +} + +export interface BB extends Y { +>BB : Symbol(BB, Decl(index.js, 108, 1)) +>Y : Symbol(Y, Decl(index.js, 97, 1)) + + [idx: number]: {x: 0, y: 0}; +>idx : Symbol(idx, Decl(index.js, 111, 5)) +>x : Symbol(x, Decl(index.js, 111, 20)) +>y : Symbol(y, Decl(index.js, 111, 25)) +} + +export interface CC extends Y { +>CC : Symbol(CC, Decl(index.js, 112, 1)) +>Y : Symbol(Y, Decl(index.js, 97, 1)) + + [idx: string]: {x: number, y: number}; +>idx : Symbol(idx, Decl(index.js, 115, 5)) +>x : Symbol(x, Decl(index.js, 115, 20)) +>y : Symbol(y, Decl(index.js, 115, 30)) + + [idx: number]: {x: 0, y: 0}; +>idx : Symbol(idx, Decl(index.js, 116, 5)) +>x : Symbol(x, Decl(index.js, 116, 20)) +>y : Symbol(y, Decl(index.js, 116, 25)) +} + diff --git a/tests/baselines/reference/jsDeclarationsInterfaces.types b/tests/baselines/reference/jsDeclarationsInterfaces.types new file mode 100644 index 0000000000000..2e7e1576cc0db --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsInterfaces.types @@ -0,0 +1,189 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +// Pretty much all of this should be an error, (since interfaces are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export interface A {} + +export interface B { + cat: string; +>cat : string +} + +export interface C { + field: T & U; +>field : T & U + + optionalField?: T; +>optionalField : T + + readonly readonlyField: T & U; +>readonlyField : T & U + + readonly readonlyOptionalField?: U; +>readonlyOptionalField : U + + (): number; + (x: T): U; +>x : T + + (x: Q): T & Q; +>x : Q + + new (): string; + new (x: T): U; +>x : T + + new (x: Q): T & Q; +>x : Q + + method(): number; +>method : { (): number; (a: T & Q): Q & number; (a?: number): number; (...args: any[]): number; } + + method(a: T & Q): Q & number; +>method : { (): number; (a: T & Q): Q & number; (a?: number): number; (...args: any[]): number; } +>a : T & Q + + method(a?: number): number; +>method : { (): number; (a: T & Q): Q & number; (a?: number): number; (...args: any[]): number; } +>a : number + + method(...args: any[]): number; +>method : { (): number; (a: T & Q): Q & number; (a?: number): number; (...args: any[]): number; } +>args : any[] + + optMethod?(): number; +>optMethod : () => number +} + +interface G {} + +export { G }; +>G : any + +interface HH {} + +export { HH as H }; +>HH : any +>H : any + +export interface I {} +export { I as II }; +>I : any +>II : any + +export { J as JJ }; +>J : any +>JJ : any + +export interface J {} + +export interface K extends I,J { + x: string; +>x : string +} + +export interface L extends K { + y: string; +>y : string +} + +export interface M { + field: T; +>field : T +} + +export interface N extends M { + other: U; +>other : U +} + +export interface O { + [idx: string]: string; +>idx : string +} + +export interface P extends O {} + +export interface Q extends O { + [idx: string]: "ok"; +>idx : string +} + +export interface R extends O { + [idx: number]: "ok"; +>idx : number +} + +export interface S extends O { + [idx: string]: "ok"; +>idx : string + + [idx: number]: never; +>idx : number +} + +export interface T { + [idx: number]: string; +>idx : number +} + +export interface U extends T {} + + +export interface V extends T { + [idx: string]: string; +>idx : string +} + +export interface W extends T { + [idx: number]: "ok"; +>idx : number +} + +export interface X extends T { + [idx: string]: string; +>idx : string + + [idx: number]: "ok"; +>idx : number +} + +export interface Y { + [idx: string]: {x: number}; +>idx : string +>x : number + + [idx: number]: {x: number, y: number}; +>idx : number +>x : number +>y : number +} + +export interface Z extends Y {} + +export interface AA extends Y { + [idx: string]: {x: number, y: number}; +>idx : string +>x : number +>y : number +} + +export interface BB extends Y { + [idx: number]: {x: 0, y: 0}; +>idx : number +>x : 0 +>y : 0 +} + +export interface CC extends Y { + [idx: string]: {x: number, y: number}; +>idx : string +>x : number +>y : number + + [idx: number]: {x: 0, y: 0}; +>idx : number +>x : 0 +>y : 0 +} + diff --git a/tests/baselines/reference/jsDeclarationsJson.js b/tests/baselines/reference/jsDeclarationsJson.js new file mode 100644 index 0000000000000..42db91addff03 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsJson.js @@ -0,0 +1,69 @@ +//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsJson.ts] //// + +//// [index.js] +const j = require("./obj.json"); +module.exports = j; +//// [obj.json] +{ + "x": 12, + "y": 12, + "obj": { + "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] + } +} + +//// [obj.json] +{ + "x": 12, + "y": 12, + "obj": { + "items": [{ "x": 12 }, { "x": 12, "y": 12 }, { "x": 0 }, { "x": -1, "err": true }] + } +} +//// [index.js] +var j = require("./obj.json"); +module.exports = j; + + +//// [obj.d.ts] +declare const _exports: { + "x": number; + "y": number; + "obj": { + "items": ({ + "x": number; + "y"?: undefined; + "err"?: undefined; + } | { + "x": number; + "y": number; + "err"?: undefined; + } | { + "x": number; + "err": boolean; + "y"?: undefined; + })[]; + }; +}; +export = _exports; +//// [index.d.ts] +declare const j: { + "x": number; + "y": number; + "obj": { + "items": ({ + "x": number; + "y"?: undefined; + "err"?: undefined; + } | { + "x": number; + "y": number; + "err"?: undefined; + } | { + "x": number; + "err": boolean; + "y"?: undefined; + })[]; + }; +}; +export = j; diff --git a/tests/baselines/reference/jsDeclarationsJson.symbols b/tests/baselines/reference/jsDeclarationsJson.symbols new file mode 100644 index 0000000000000..9e276decbc6b5 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsJson.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +const j = require("./obj.json"); +>j : Symbol(j, Decl(index.js, 0, 5)) +>require : Symbol(require) +>"./obj.json" : Symbol("tests/cases/conformance/jsdoc/declarations/obj", Decl(obj.json, 0, 0)) + +module.exports = j; +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(export=, Decl(index.js, 0, 32)) +>exports : Symbol(export=, Decl(index.js, 0, 32)) +>j : Symbol(j, Decl(index.js, 0, 5)) + +=== tests/cases/conformance/jsdoc/declarations/obj.json === +{ + "x": 12, +>"x" : Symbol("x", Decl(obj.json, 0, 1)) + + "y": 12, +>"y" : Symbol("y", Decl(obj.json, 1, 12)) + + "obj": { +>"obj" : Symbol("obj", Decl(obj.json, 2, 12)) + + "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] +>"items" : Symbol("items", Decl(obj.json, 3, 12)) +>"x" : Symbol("x", Decl(obj.json, 4, 19)) +>"x" : Symbol("x", Decl(obj.json, 4, 30)) +>"y" : Symbol("y", Decl(obj.json, 4, 38)) +>"x" : Symbol("x", Decl(obj.json, 4, 50)) +>"x" : Symbol("x", Decl(obj.json, 4, 60)) +>"err" : Symbol("err", Decl(obj.json, 4, 68)) + } +} diff --git a/tests/baselines/reference/jsDeclarationsJson.types b/tests/baselines/reference/jsDeclarationsJson.types new file mode 100644 index 0000000000000..aaab20ac36a2e --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsJson.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +const j = require("./obj.json"); +>j : { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; } +>require("./obj.json") : { "x": number; "y": number; "obj": { "items": ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[]; }; } +>require : any +>"./obj.json" : "./obj.json" + +module.exports = j; +>module.exports = j : { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; } +>module.exports : { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; } +>module : { "tests/cases/conformance/jsdoc/declarations/index": { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; }; } +>exports : { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; } +>j : { "x": number; "y": number; "obj": { "items": ({ "x": number; "y"?: undefined; "err"?: undefined; } | { "x": number; "y": number; "err"?: undefined; } | { "x": number; "err": boolean; "y"?: undefined; })[]; }; } + +=== tests/cases/conformance/jsdoc/declarations/obj.json === +{ +>{ "x": 12, "y": 12, "obj": { "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] }} : { "x": number; "y": number; "obj": { "items": ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[]; }; } + + "x": 12, +>"x" : number +>12 : 12 + + "y": 12, +>"y" : number +>12 : 12 + + "obj": { +>"obj" : { "items": ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[]; } +>{ "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] } : { "items": ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[]; } + + "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] +>"items" : ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[] +>[{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] : ({ "x": number; } | { "x": number; "y": number; } | { "x": number; "err": boolean; })[] +>{"x": 12} : { "x": number; } +>"x" : number +>12 : 12 +>{"x": 12, "y": 12} : { "x": number; "y": number; } +>"x" : number +>12 : 12 +>"y" : number +>12 : 12 +>{"x": 0} : { "x": number; } +>"x" : number +>0 : 0 +>{"x": -1, "err": true} : { "x": number; "err": boolean; } +>"x" : number +>-1 : -1 +>1 : 1 +>"err" : boolean +>true : true + } +} diff --git a/tests/baselines/reference/jsDeclarationsTypeAliases.js b/tests/baselines/reference/jsDeclarationsTypeAliases.js new file mode 100644 index 0000000000000..94eda9f8617b7 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsTypeAliases.js @@ -0,0 +1,63 @@ +//// [index.js] +export {}; // flag file as module +/** + * @typedef {string | number | symbol} PropName + */ + +/** + * Callback + * + * @callback NumberToStringCb + * @param {number} a + * @returns {string} + */ + +/** + * @template T + * @typedef {T & {name: string}} MixinName + */ + +/** + * Identity function + * + * @template T + * @callback Identity + * @param {T} x + * @returns {T} + */ + + +//// [index.js] +"use strict"; +exports.__esModule = true; +/** + * @typedef {string | number | symbol} PropName + */ +/** + * Callback + * + * @callback NumberToStringCb + * @param {number} a + * @returns {string} + */ +/** + * @template T + * @typedef {T & {name: string}} MixinName + */ +/** + * Identity function + * + * @template T + * @callback Identity + * @param {T} x + * @returns {T} + */ + + +//// [index.d.ts] +export type PropName = string | number | symbol; +export type NumberToStringCb = (a: number) => string; +export type MixinName = T & { + name: string; +}; +export type Identity = (x: T) => T; diff --git a/tests/baselines/reference/jsDeclarationsTypeAliases.symbols b/tests/baselines/reference/jsDeclarationsTypeAliases.symbols new file mode 100644 index 0000000000000..5caacfaea2351 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsTypeAliases.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export {}; // flag file as module +No type information for this code./** +No type information for this code. * @typedef {string | number | symbol} PropName +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * Callback +No type information for this code. * +No type information for this code. * @callback NumberToStringCb +No type information for this code. * @param {number} a +No type information for this code. * @returns {string} +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * @template T +No type information for this code. * @typedef {T & {name: string}} MixinName +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * Identity function +No type information for this code. * +No type information for this code. * @template T +No type information for this code. * @callback Identity +No type information for this code. * @param {T} x +No type information for this code. * @returns {T} +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsTypeAliases.types b/tests/baselines/reference/jsDeclarationsTypeAliases.types new file mode 100644 index 0000000000000..5caacfaea2351 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsTypeAliases.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +export {}; // flag file as module +No type information for this code./** +No type information for this code. * @typedef {string | number | symbol} PropName +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * Callback +No type information for this code. * +No type information for this code. * @callback NumberToStringCb +No type information for this code. * @param {number} a +No type information for this code. * @returns {string} +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * @template T +No type information for this code. * @typedef {T & {name: string}} MixinName +No type information for this code. */ +No type information for this code. +No type information for this code./** +No type information for this code. * Identity function +No type information for this code. * +No type information for this code. * @template T +No type information for this code. * @callback Identity +No type information for this code. * @param {T} x +No type information for this code. * @returns {T} +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.errors.txt b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.errors.txt index b05fc6fa6d944..fb0c214ddf657 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.errors.txt +++ b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.errors.txt @@ -1,8 +1,6 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. tests/cases/compiler/a.ts(1,10): error TS2393: Duplicate function implementation. -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== tests/cases/compiler/b.js (0 errors) ==== function foo() { return 10; diff --git a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.js b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.js index 9b64450936186..20984ae5b9983 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.js +++ b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementation.js @@ -21,3 +21,4 @@ function foo() { //// [out.d.ts] +declare function foo(): number; diff --git a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.errors.txt b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.errors.txt index 82dbc27db0f40..78eb22546e8b0 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.errors.txt +++ b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.errors.txt @@ -1,8 +1,6 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. tests/cases/compiler/a.ts(1,10): error TS2393: Duplicate function implementation. -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== tests/cases/compiler/a.ts (1 errors) ==== function foo() { ~~~ diff --git a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.js b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.js index d7965e91be1d3..9bd3913694218 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.js +++ b/tests/baselines/reference/jsFileCompilationDuplicateFunctionImplementationFileOrderReversed.js @@ -22,3 +22,4 @@ function foo() { //// [out.d.ts] +declare function foo(): number; diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariable.errors.txt b/tests/baselines/reference/jsFileCompilationDuplicateVariable.errors.txt deleted file mode 100644 index f8ae4a1ba74cd..0000000000000 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariable.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== - var x = 10; - -==== tests/cases/compiler/b.js (0 errors) ==== - var x = "hello"; // No error is recorded here and declaration file will show this as number \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariable.js b/tests/baselines/reference/jsFileCompilationDuplicateVariable.js index a70637bc7c066..549bd0dfe9a28 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariable.js +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariable.js @@ -4,12 +4,28 @@ var x = 10; //// [b.js] -var x = "hello"; // No error is recorded here and declaration file will show this as number +var x = "hello"; // Error is recorded here, but suppressed because the js file isn't checked //// [out.js] var x = 10; -var x = "hello"; // No error is recorded here and declaration file will show this as number +var x = "hello"; // Error is recorded here, but suppressed because the js file isn't checked //// [out.d.ts] declare var x: number; +declare var x: string; + + +//// [DtsFileErrors] + + +out.d.ts(2,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'number', but here has type 'string'. + + +==== out.d.ts (1 errors) ==== + declare var x: number; + declare var x: string; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'number', but here has type 'string'. +!!! related TS6203 out.d.ts:1:13: 'x' was also declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariable.symbols b/tests/baselines/reference/jsFileCompilationDuplicateVariable.symbols index 9bfc61a64f85a..a82dee6bb9344 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariable.symbols +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariable.symbols @@ -3,6 +3,6 @@ var x = 10; >x : Symbol(x, Decl(a.ts, 0, 3), Decl(b.js, 0, 3)) === tests/cases/compiler/b.js === -var x = "hello"; // No error is recorded here and declaration file will show this as number +var x = "hello"; // Error is recorded here, but suppressed because the js file isn't checked >x : Symbol(x, Decl(a.ts, 0, 3), Decl(b.js, 0, 3)) diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariable.types b/tests/baselines/reference/jsFileCompilationDuplicateVariable.types index bcd115b1577b9..bd82bb53df6d0 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariable.types +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariable.types @@ -4,7 +4,7 @@ var x = 10; >10 : 10 === tests/cases/compiler/b.js === -var x = "hello"; // No error is recorded here and declaration file will show this as number +var x = "hello"; // Error is recorded here, but suppressed because the js file isn't checked >x : number >"hello" : "hello" diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.errors.txt b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.errors.txt index 9e46d6225a2c8..540970836d656 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.errors.txt +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.errors.txt @@ -1,13 +1,11 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. tests/cases/compiler/a.ts(1,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'number'. -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== tests/cases/compiler/b.js (0 errors) ==== var x = "hello"; ==== tests/cases/compiler/a.ts (1 errors) ==== - var x = 10; // Error reported so no declaration file generated? + var x = 10; // Error reported ~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'number'. !!! related TS6203 tests/cases/compiler/b.js:1:5: 'x' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.js b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.js index fd9da7c71066b..83b33fdd02b4d 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.js +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.js @@ -4,12 +4,13 @@ var x = "hello"; //// [a.ts] -var x = 10; // Error reported so no declaration file generated? +var x = 10; // Error reported //// [out.js] var x = "hello"; -var x = 10; // Error reported so no declaration file generated? +var x = 10; // Error reported //// [out.d.ts] declare var x: string; +declare var x: string; diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.symbols b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.symbols index 0b1360f8f5abe..f6f944c8642bc 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.symbols +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.symbols @@ -3,6 +3,6 @@ var x = "hello"; >x : Symbol(x, Decl(b.js, 0, 3), Decl(a.ts, 0, 3)) === tests/cases/compiler/a.ts === -var x = 10; // Error reported so no declaration file generated? +var x = 10; // Error reported >x : Symbol(x, Decl(b.js, 0, 3), Decl(a.ts, 0, 3)) diff --git a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.types b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.types index b88f42f0c28a9..48a2ee9e9ef0a 100644 --- a/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.types +++ b/tests/baselines/reference/jsFileCompilationDuplicateVariableErrorReported.types @@ -4,7 +4,7 @@ var x = "hello"; >"hello" : "hello" === tests/cases/compiler/a.ts === -var x = 10; // Error reported so no declaration file generated? +var x = 10; // Error reported >x : string >10 : 10 diff --git a/tests/baselines/reference/jsFileCompilationEmitDeclarations.errors.txt b/tests/baselines/reference/jsFileCompilationEmitDeclarations.errors.txt deleted file mode 100644 index 3e89f9c9436f5..0000000000000 --- a/tests/baselines/reference/jsFileCompilationEmitDeclarations.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== - class c { - } - -==== tests/cases/compiler/b.js (0 errors) ==== - function foo() { - } - \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationEmitDeclarations.js b/tests/baselines/reference/jsFileCompilationEmitDeclarations.js index 312f3b6b22953..2671a580cbc7e 100644 --- a/tests/baselines/reference/jsFileCompilationEmitDeclarations.js +++ b/tests/baselines/reference/jsFileCompilationEmitDeclarations.js @@ -22,3 +22,4 @@ function foo() { //// [out.d.ts] declare class c { } +declare function foo(): void; diff --git a/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.errors.txt b/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.errors.txt deleted file mode 100644 index 0cefa2eedac20..0000000000000 --- a/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== - class c { - } - -==== tests/cases/compiler/b.js (0 errors) ==== - /// - function foo() { - } - -==== tests/cases/compiler/c.js (0 errors) ==== - function bar() { - } \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.js b/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.js index 625c09964c065..128ec0c3e357e 100644 --- a/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.js +++ b/tests/baselines/reference/jsFileCompilationEmitTrippleSlashReference.js @@ -29,3 +29,5 @@ function foo() { //// [out.d.ts] declare class c { } +declare function bar(): void; +declare function foo(): void; diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.errors.txt b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.errors.txt index c9937ecd3592e..b19009a468b97 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.errors.txt +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.errors.txt @@ -1,9 +1,7 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file. Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. !!! error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would overwrite input file. !!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. ==== tests/cases/compiler/a.ts (0 errors) ==== @@ -12,7 +10,7 @@ error TS5055: Cannot write file 'tests/cases/compiler/c.js' because it would ove ==== tests/cases/compiler/b.ts (0 errors) ==== /// - // b.d.ts should have c.js as the reference path since we dont emit declarations for js files + // b.d.ts should have c.d.ts as the reference path function foo() { } diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.js b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.js index f9dcb3b2f71a8..7a0942b5ac718 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.js +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.js @@ -6,7 +6,7 @@ class c { //// [b.ts] /// -// b.d.ts should have c.js as the reference path since we dont emit declarations for js files +// b.d.ts should have c.d.ts as the reference path function foo() { } @@ -22,7 +22,7 @@ var c = /** @class */ (function () { }()); //// [b.js] /// -// b.d.ts should have c.js as the reference path since we dont emit declarations for js files +// b.d.ts should have c.d.ts as the reference path function foo() { } @@ -30,6 +30,8 @@ function foo() { //// [a.d.ts] declare class c { } +//// [c.d.ts] +declare function bar(): void; //// [b.d.ts] -/// +/// declare function foo(): void; diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.symbols b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.symbols index 424fd85c16587..7f3b8e3c6f158 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.symbols +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.symbols @@ -5,7 +5,7 @@ class c { === tests/cases/compiler/b.ts === /// -// b.d.ts should have c.js as the reference path since we dont emit declarations for js files +// b.d.ts should have c.d.ts as the reference path function foo() { >foo : Symbol(foo, Decl(b.ts, 0, 0)) } diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.types b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.types index f8b82383ac47c..5ef6333da21c0 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.types +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.types @@ -5,7 +5,7 @@ class c { === tests/cases/compiler/b.ts === /// -// b.d.ts should have c.js as the reference path since we dont emit declarations for js files +// b.d.ts should have c.d.ts as the reference path function foo() { >foo : () => void } diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.errors.txt b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.errors.txt deleted file mode 100644 index 441514014799d..0000000000000 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== - class c { - } - -==== tests/cases/compiler/b.ts (0 errors) ==== - /// - // error on above reference when emitting declarations - function foo() { - } - -==== tests/cases/compiler/c.js (0 errors) ==== - function bar() { - } \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.js b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.js index e10b3e43fb854..9c60af0c79c06 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.js +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.js @@ -6,7 +6,6 @@ class c { //// [b.ts] /// -// error on above reference when emitting declarations function foo() { } @@ -23,13 +22,12 @@ var c = /** @class */ (function () { function bar() { } /// -// error on above reference when emitting declarations function foo() { } //// [out.d.ts] -/// declare class c { } +declare function bar(): void; declare function foo(): void; diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.symbols b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.symbols index 544fe53f425af..967d023d2c2f8 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.symbols +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.symbols @@ -5,7 +5,6 @@ class c { === tests/cases/compiler/b.ts === /// -// error on above reference when emitting declarations function foo() { >foo : Symbol(foo, Decl(b.ts, 0, 0)) } diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.types b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.types index 8aafb9f61d034..b34de54d704f8 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.types +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.types @@ -5,7 +5,6 @@ class c { === tests/cases/compiler/b.ts === /// -// error on above reference when emitting declarations function foo() { >foo : () => void } diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.errors.txt b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.errors.txt deleted file mode 100644 index fb6c801b42e7c..0000000000000 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== - class c { - } - -==== tests/cases/compiler/b.ts (0 errors) ==== - /// - // b.d.ts should have c.js as the reference path since we dont emit declarations for js files - function foo() { - } - -==== tests/cases/compiler/c.js (0 errors) ==== - function bar() { - } \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.js b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.js index 5e12d775bb139..15617a53a508d 100644 --- a/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.js +++ b/tests/baselines/reference/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOutDir.js @@ -33,6 +33,8 @@ function foo() { //// [a.d.ts] declare class c { } +//// [c.d.ts] +declare function bar(): void; //// [b.d.ts] -/// +/// declare function foo(): void; diff --git a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.errors.txt b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.errors.txt deleted file mode 100644 index 20a9c81ea9c62..0000000000000 --- a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/b.js (0 errors) ==== - let a = 10; - b = 30; - -==== tests/cases/compiler/a.ts (0 errors) ==== - let b = 30; - a = 10; - \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.js b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.js index 16e4b7a3011f2..15a1e8d753354 100644 --- a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.js +++ b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder.js @@ -17,4 +17,5 @@ a = 10; //// [out.d.ts] +declare let a: number; declare let b: number; diff --git a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt index 6fc8df185006c..4ffbabdd06394 100644 --- a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt +++ b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt @@ -1,8 +1,6 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. tests/cases/compiler/a.ts(2,1): error TS2448: Block-scoped variable 'a' used before its declaration. -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== tests/cases/compiler/a.ts (1 errors) ==== let b = 30; a = 10; diff --git a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.js b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.js index 890b1c22f717e..641a89c1c5049 100644 --- a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.js +++ b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.js @@ -17,3 +17,4 @@ b = 30; //// [out.d.ts] declare let b: number; +declare let a: number; diff --git a/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.errors.txt b/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.errors.txt deleted file mode 100644 index 7133188adc0ca..0000000000000 --- a/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5053: Option 'allowJs' cannot be specified with option 'composite'. - - -!!! error TS5053: Option 'allowJs' cannot be specified with option 'composite'. -==== tests/cases/compiler/a.ts (0 errors) ==== - class c { - } - -==== tests/cases/compiler/b.js (0 errors) ==== - function foo() { - } - \ No newline at end of file diff --git a/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.js b/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.js index e34edb10ff426..9a1dbcd530140 100644 --- a/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.js +++ b/tests/baselines/reference/jsFileCompilationWithEnabledCompositeOption.js @@ -22,3 +22,4 @@ function foo() { //// [out.d.ts] declare class c { } +declare function foo(): void; diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/amd/test.d.ts b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/amd/test.d.ts index 4c0b8989316ef..bbae04a30bf94 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/amd/test.d.ts +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/amd/test.d.ts @@ -1 +1,2 @@ declare var test: number; +declare var test2: number; diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs.errors.txt b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs.errors.txt index 6a3c9863cc590..5471371449aa1 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs.errors.txt +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs.errors.txt @@ -1,16 +1,13 @@ DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json(3,5): error TS6082: Only 'amd' and 'system' modules are supported alongside --out. -DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json (2 errors) ==== +==== DifferentNamesNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ==== { "compilerOptions": { "out": "test.js", ~~~~~ !!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out. "allowJs": true - ~~~~~~~~~ -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. } } ==== DifferentNamesNotSpecifiedWithAllowJs/a.ts (0 errors) ==== diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/test.d.ts b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/test.d.ts index 4c0b8989316ef..bbae04a30bf94 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/test.d.ts +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/node/test.d.ts @@ -1 +1,2 @@ declare var test: number; +declare var test2: number; diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/amd/test.d.ts b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/amd/test.d.ts index 4c0b8989316ef..bbae04a30bf94 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/amd/test.d.ts +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/amd/test.d.ts @@ -1 +1,2 @@ declare var test: number; +declare var test2: number; diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesSpecifiedWithAllowJs.errors.txt b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesSpecifiedWithAllowJs.errors.txt index c2849fae3a580..3c80f199817ad 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesSpecifiedWithAllowJs.errors.txt +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/jsFileCompilationDifferentNamesSpecifiedWithAllowJs.errors.txt @@ -1,16 +1,13 @@ DifferentNamesSpecifiedWithAllowJs/tsconfig.json(3,5): error TS6082: Only 'amd' and 'system' modules are supported alongside --out. -DifferentNamesSpecifiedWithAllowJs/tsconfig.json(4,5): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== DifferentNamesSpecifiedWithAllowJs/tsconfig.json (2 errors) ==== +==== DifferentNamesSpecifiedWithAllowJs/tsconfig.json (1 errors) ==== { "compilerOptions": { "out": "test.js", ~~~~~ !!! error TS6082: Only 'amd' and 'system' modules are supported alongside --out. "allowJs": true - ~~~~~~~~~ -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. }, "files": [ "a.ts", "b.js" ] } diff --git a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/test.d.ts b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/test.d.ts index 4c0b8989316ef..bbae04a30bf94 100644 --- a/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/test.d.ts +++ b/tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/node/test.d.ts @@ -1 +1,2 @@ declare var test: number; +declare var test2: number; diff --git a/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/amd/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt b/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/amd/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt index aa7418ccc1420..45cdfd7a3bc42 100644 --- a/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/amd/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt +++ b/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/amd/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt @@ -1,14 +1,15 @@ +error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.d.ts' because it would overwrite input file. + Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file. Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. +!!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.d.ts' because it would overwrite input file. +!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. !!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file. !!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ==== +==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (0 errors) ==== { "compilerOptions": { "allowJs": true } } - ~~~~~~~~~ -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== SameNameDTsNotSpecifiedWithAllowJs/a.d.ts (0 errors) ==== declare var a: number; ==== SameNameDTsNotSpecifiedWithAllowJs/a.js (0 errors) ==== diff --git a/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/node/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt b/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/node/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt index aa7418ccc1420..45cdfd7a3bc42 100644 --- a/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/node/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt +++ b/tests/baselines/reference/project/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs/node/jsFileCompilationSameNameDtsNotSpecifiedWithAllowJs.errors.txt @@ -1,14 +1,15 @@ +error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.d.ts' because it would overwrite input file. + Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file. Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json(1,24): error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. +!!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.d.ts' because it would overwrite input file. +!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. !!! error TS5055: Cannot write file 'SameNameDTsNotSpecifiedWithAllowJs/a.js' because it would overwrite input file. !!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (1 errors) ==== +==== SameNameDTsNotSpecifiedWithAllowJs/tsconfig.json (0 errors) ==== { "compilerOptions": { "allowJs": true } } - ~~~~~~~~~ -!!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. ==== SameNameDTsNotSpecifiedWithAllowJs/a.d.ts (0 errors) ==== declare var a: number; ==== SameNameDTsNotSpecifiedWithAllowJs/a.js (0 errors) ==== diff --git a/tests/baselines/reference/requireOfJsonFileWithDeclaration.js b/tests/baselines/reference/requireOfJsonFileWithDeclaration.js index 2cb5085ffb7ff..1d099199cedd8 100644 --- a/tests/baselines/reference/requireOfJsonFileWithDeclaration.js +++ b/tests/baselines/reference/requireOfJsonFileWithDeclaration.js @@ -32,5 +32,11 @@ if (x) { } +//// [out/b.d.ts] +declare const _exports: { + "a": boolean; + "b": string; +}; +export = _exports; //// [out/file1.d.ts] export {}; diff --git a/tests/cases/compiler/jsFileCompilationDuplicateVariable.ts b/tests/cases/compiler/jsFileCompilationDuplicateVariable.ts index cf2e27de885e5..b100fc748c83d 100644 --- a/tests/cases/compiler/jsFileCompilationDuplicateVariable.ts +++ b/tests/cases/compiler/jsFileCompilationDuplicateVariable.ts @@ -5,4 +5,4 @@ var x = 10; // @filename: b.js -var x = "hello"; // No error is recorded here and declaration file will show this as number \ No newline at end of file +var x = "hello"; // Error is recorded here, but suppressed because the js file isn't checked \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationDuplicateVariableErrorReported.ts b/tests/cases/compiler/jsFileCompilationDuplicateVariableErrorReported.ts index 05b750fe6082b..11b7711eb0eff 100644 --- a/tests/cases/compiler/jsFileCompilationDuplicateVariableErrorReported.ts +++ b/tests/cases/compiler/jsFileCompilationDuplicateVariableErrorReported.ts @@ -5,4 +5,4 @@ var x = "hello"; // @filename: a.ts -var x = 10; // Error reported so no declaration file generated? \ No newline at end of file +var x = 10; // Error reported \ No newline at end of file diff --git a/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.ts b/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.ts index 1741e3c280270..347c501c88ef5 100644 --- a/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.ts +++ b/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithNoOut.ts @@ -6,7 +6,7 @@ class c { // @filename: b.ts /// -// b.d.ts should have c.js as the reference path since we dont emit declarations for js files +// b.d.ts should have c.d.ts as the reference path function foo() { } diff --git a/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.ts b/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.ts index 35228678bb72a..d2173ba28ef8c 100644 --- a/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.ts +++ b/tests/cases/compiler/jsFileCompilationErrorOnDeclarationsWithJsFileReferenceWithOut.ts @@ -7,7 +7,6 @@ class c { // @filename: b.ts /// -// error on above reference when emitting declarations function foo() { } diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClasses.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClasses.ts new file mode 100644 index 0000000000000..33438be3b369c --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClasses.ts @@ -0,0 +1,187 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js +export class A {} + +export class B { + static cat = "cat"; +} + +export class C { + static Cls = class {} +} + +export class D { + /** + * @param {number} a + * @param {number} b + */ + constructor(a, b) {} +} + +/** + * @template T,U + */ +export class E { + /** + * @type {T & U} + */ + field; + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {T & U} + * @readonly + */ + readonlyField; + + initializedField = 12; + + /** + * @return {U} + */ + get f1() { return /** @type {*} */(null); } + + /** + * @param {U} _p + */ + set f1(_p) {} + + /** + * @return {U} + */ + get f2() { return /** @type {*} */(null); } + + /** + * @param {U} _p + */ + set f3(_p) {} + + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} + + + /** + * @type {string} + */ + static staticField; + + // @readonly is currently unsupported, it seems - included here just in case that changes + /** + * @type {string} + * @readonly + */ + static staticReadonlyField; + + static staticInitializedField = 12; + + /** + * @return {string} + */ + static get s1() { return ""; } + + /** + * @param {string} _p + */ + static set s1(_p) {} + + /** + * @return {string} + */ + static get s2() { return ""; } + + /** + * @param {string} _p + */ + static set s3(_p) {} +} + +/** + * @template T,U + */ +export class F { + /** + * @type {T & U} + */ + field; + /** + * @param {T} a + * @param {U} b + */ + constructor(a, b) {} + + /** + * @template A,B + * @param {A} a + * @param {B} b + */ + static create(a, b) { return new F(a, b); } +} + +class G {} + +export { G }; + +class HH {} + +export { HH as H }; + +export class I {} +export { I as II }; + +export { J as JJ }; +export class J {} + + +export class K { + constructor() { + this.p1 = 12; + this.p2 = "ok"; + } + + method() { + return this.p1; + } +} + +export class L extends K {} + +export class M extends null { + constructor() { + this.prop = 12; + } +} + + +/** + * @template T + */ +export class N extends L { + /** + * @param {T} param + */ + constructor(param) { + super(); + this.another = param; + } +} + +/** + * @template U + * @extends {N} + */ +export class O extends N { + /** + * @param {U} param + */ + constructor(param) { + super(param); + this.another2 = param; + } +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassesErr.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassesErr.ts new file mode 100644 index 0000000000000..d627fa8236bd7 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassesErr.ts @@ -0,0 +1,76 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js + +// Pretty much all of this should be an error, (since index signatures and generics are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export class M { + field: T; +} + +export class N extends M { + other: U; +} + +export class O { + [idx: string]: string; +} + +export class P extends O {} + +export class Q extends O { + [idx: string]: "ok"; +} + +export class R extends O { + [idx: number]: "ok"; +} + +export class S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} + +export class T { + [idx: number]: string; +} + +export class U extends T {} + + +export class V extends T { + [idx: string]: string; +} + +export class W extends T { + [idx: number]: "ok"; +} + +export class X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} + +export class Y { + [idx: string]: {x: number}; + [idx: number]: {x: number, y: number}; +} + +export class Z extends Y {} + +export class AA extends Y { + [idx: string]: {x: number, y: number}; +} + +export class BB extends Y { + [idx: number]: {x: 0, y: 0}; +} + +export class CC extends Y { + [idx: string]: {x: number, y: number}; + [idx: number]: {x: 0, y: 0}; +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefault.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefault.ts new file mode 100644 index 0000000000000..35543033b7a4e --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefault.ts @@ -0,0 +1,42 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index1.js +export default 12; + +// @filename: index2.js +export default function foo() { + return foo; +} +export const x = foo; +export { foo as bar }; + +// @filename: index3.js +export default class Foo { + a = /** @type {Foo} */(null); +}; +export const X = Foo; +export { Foo as Bar }; + +// @filename: index4.js +import Fab from "./index3"; +class Bar extends Fab { + x = /** @type {Bar} */(null); +} +export default Bar; + +// @filename: index5.js +// merge type alias and const (OK) +export default 12; +/** + * @typedef {string | number} default + */ + +// @filename: index6.js +// merge type alias and function (OK) +export default function func() {}; +/** + * @typedef {string | number} default + */ diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefaultsErr.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefaultsErr.ts new file mode 100644 index 0000000000000..4cd1fc5ca6f25 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsDefaultsErr.ts @@ -0,0 +1,30 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index1.js +// merge type alias and alias (should error, see #32367) +class Cls { + x = 12; + static y = "ok" +} +export default Cls; +/** + * @typedef {string | number} default + */ + +// @filename: index2.js +// merge type alias and class (error message improvement needed, see #32368) +export default class C {}; +/** + * @typedef {string | number} default + */ + +// @filename: index3.js +// merge type alias and variable (beharior is borked, see #32366) +const x = 12; +export {x as default}; +/** + * @typedef {string | number} default + */ diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsEnums.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsEnums.ts new file mode 100644 index 0000000000000..e0300a4ddc43b --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsEnums.ts @@ -0,0 +1,68 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js + +// Pretty much all of this should be an error, (since enums are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export enum A {} + +export enum B { + Member +} + +enum C {} + +export { C }; + +enum DD {} + +export { DD as D }; + +export enum E {} +export { E as EE }; + +export { F as FF }; +export enum F {} + +export enum G { + A = 1, + B, + C +} + +export enum H { + A = "a", + B = "b" +} + +export enum I { + A = "a", + B = 0, + C +} + +export const enum J { + A = 1, + B, + C +} + +export enum K { + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, +} + +export const enum L { + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + Mask = A | B | C, +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctions.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctions.ts new file mode 100644 index 0000000000000..65247ba282db5 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctions.ts @@ -0,0 +1,62 @@ +// @allowJs: true +// @checkJs: true +// @outDir: ./out +// @declaration: true +// @filename: index.js +export function a() {} + +export function b() {} +b.cat = "cat"; + +export function c() {} +c.Cls = class {} + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +export function d(a, b) { return /** @type {*} */(null); } + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +export function e(a, b) { return /** @type {*} */(null); } + +/** + * @template T + * @param {T} a + */ +export function f(a) { + return a; +} +f.self = f; + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function g(a, b) { + return a.x && b.y(); +} + +export { g }; + +/** + * @param {{x: string}} a + * @param {{y: typeof b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} + +export { hh as h }; + +export function i() {} +export { i as ii }; + +export { j as jj }; +export function j() {} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctionsCjs.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctionsCjs.ts new file mode 100644 index 0000000000000..329ebda040f13 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsFunctionsCjs.ts @@ -0,0 +1,63 @@ +// @allowJs: true +// @checkJs: true +// @outDir: ./out +// @declaration: true +// @filename: index.js +module.exports.a = function a() {} + +module.exports.b = function b() {} +module.exports.b.cat = "cat"; + +module.exports.c = function c() {} +module.exports.c.Cls = class {} + +/** + * @param {number} a + * @param {number} b + * @return {string} + */ +module.exports.d = function d(a, b) { return /** @type {*} */(null); } + +/** + * @template T,U + * @param {T} a + * @param {U} b + * @return {T & U} + */ +module.exports.e = function e(a, b) { return /** @type {*} */(null); } + +/** + * @template T + * @param {T} a + */ +module.exports.f = function f(a) { + return a; +} +module.exports.f.self = module.exports.f; + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function g(a, b) { + return a.x && b.y(); +} + +module.exports.g = g; + +/** + * @param {{x: string}} a + * @param {{y: typeof module.exports.b}} b + */ +function hh(a, b) { + return a.x && b.y(); +} + +module.exports.h = hh; + +module.exports.i = function i() {} +module.exports.ii = module.exports.i; + +// note that this last one doesn't make much sense in cjs, since exports aren't hoisted bindings +module.exports.jj = module.exports.j; +module.exports.j = function j() {} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsInterfaces.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsInterfaces.ts new file mode 100644 index 0000000000000..1eb04215792f4 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsInterfaces.ts @@ -0,0 +1,125 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js + +// Pretty much all of this should be an error, (since interfaces are forbidden in js), +// but we should be able to synthesize declarations from the symbols regardless + +export interface A {} + +export interface B { + cat: string; +} + +export interface C { + field: T & U; + optionalField?: T; + readonly readonlyField: T & U; + readonly readonlyOptionalField?: U; + (): number; + (x: T): U; + (x: Q): T & Q; + + new (): string; + new (x: T): U; + new (x: Q): T & Q; + + method(): number; + method(a: T & Q): Q & number; + method(a?: number): number; + method(...args: any[]): number; + + optMethod?(): number; +} + +interface G {} + +export { G }; + +interface HH {} + +export { HH as H }; + +export interface I {} +export { I as II }; + +export { J as JJ }; +export interface J {} + +export interface K extends I,J { + x: string; +} + +export interface L extends K { + y: string; +} + +export interface M { + field: T; +} + +export interface N extends M { + other: U; +} + +export interface O { + [idx: string]: string; +} + +export interface P extends O {} + +export interface Q extends O { + [idx: string]: "ok"; +} + +export interface R extends O { + [idx: number]: "ok"; +} + +export interface S extends O { + [idx: string]: "ok"; + [idx: number]: never; +} + +export interface T { + [idx: number]: string; +} + +export interface U extends T {} + + +export interface V extends T { + [idx: string]: string; +} + +export interface W extends T { + [idx: number]: "ok"; +} + +export interface X extends T { + [idx: string]: string; + [idx: number]: "ok"; +} + +export interface Y { + [idx: string]: {x: number}; + [idx: number]: {x: number, y: number}; +} + +export interface Z extends Y {} + +export interface AA extends Y { + [idx: string]: {x: number, y: number}; +} + +export interface BB extends Y { + [idx: number]: {x: 0, y: 0}; +} + +export interface CC extends Y { + [idx: string]: {x: number, y: number}; + [idx: number]: {x: 0, y: 0}; +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsJson.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsJson.ts new file mode 100644 index 0000000000000..a98c41d172827 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsJson.ts @@ -0,0 +1,17 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @resolveJsonModule: true +// @outDir: ./out +// @declaration: true +// @filename: index.js +const j = require("./obj.json"); +module.exports = j; +// @filename: obj.json +{ + "x": 12, + "y": 12, + "obj": { + "items": [{"x": 12}, {"x": 12, "y": 12}, {"x": 0}, {"x": -1, "err": true}] + } +} \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeAliases.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeAliases.ts new file mode 100644 index 0000000000000..809400d967813 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsTypeAliases.ts @@ -0,0 +1,32 @@ +// @allowJs: true +// @checkJs: true +// @outDir: ./out +// @declaration: true +// @filename: index.js + +export {}; // flag file as module +/** + * @typedef {string | number | symbol} PropName + */ + +/** + * Callback + * + * @callback NumberToStringCb + * @param {number} a + * @returns {string} + */ + +/** + * @template T + * @typedef {T & {name: string}} MixinName + */ + +/** + * Identity function + * + * @template T + * @callback Identity + * @param {T} x + * @returns {T} + */ diff --git a/tests/cases/fourslash/jsFileCompilationDuplicateFunctionImplementation.ts b/tests/cases/fourslash/jsFileCompilationDuplicateFunctionImplementation.ts index 927d84ed8bace..26497f9f5a900 100644 --- a/tests/cases/fourslash/jsFileCompilationDuplicateFunctionImplementation.ts +++ b/tests/cases/fourslash/jsFileCompilationDuplicateFunctionImplementation.ts @@ -20,7 +20,7 @@ verify.getSemanticDiagnostics([{ }]); verify.verifyGetEmitOutputContentsForCurrentFile([ { name: "out.js", text: "function foo() { return 10; }\r\nfunction foo() { return 30; }\r\n", writeByteOrderMark: false }, - { name: "out.d.ts", text: "", writeByteOrderMark: false }]); + { name: "out.d.ts", text: "declare function foo(): number;\r\n", writeByteOrderMark: false }]); goTo.marker("2"); verify.getSemanticDiagnostics([{ message: "Duplicate function implementation.",