From 701c5f3687634bdd51f4b7c2e6fb8be56b4dc81f Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 9 Sep 2021 21:00:38 -0700 Subject: [PATCH 01/38] prototype creation for method override completion snippet --- src/server/protocol.ts | 2 +- src/services/completions.ts | 64 ++++++++++++++++++- .../fourslash/completionsOverridingMethod.ts | 36 +++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionsOverridingMethod.ts diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 6147077051b52..46badf082fa7c 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2289,7 +2289,7 @@ namespace ts.server.protocol { /** * Human-readable description of the `source`. */ - sourceDisplay?: SymbolDisplayPart[]; + sourceDisplay?: SymbolDisplayPart[]; /** * If true, this completion should be highlighted as recommended. There will only be one of these. * This will be set when we know the user should write an expression with a certain type and that type is an enum or constructable class. diff --git a/src/services/completions.ts b/src/services/completions.ts index 764e64c32e104..c18ddff2cc59e 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -662,10 +662,18 @@ namespace ts.Completions { sourceDisplay = [textPart(origin.moduleSpecifier)]; if (importCompletionNode) { ({ insertText, replacementSpan } = getInsertTextAndReplacementSpanForImportCompletion(name, importCompletionNode, origin, useSemicolons, options, preferences)); - isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined; + isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined; // >> Using snippet here. } } + if (isMethodOverrideCompletion(symbol, location)) { + ({ insertText } = getInsertTextForMethodOverrideCompletion(typeChecker, options, name, symbol, location)); + // replacementSpan = undefined; // >> TODO + isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined; + hasAction = true; + } + + // >> Should this actually be here and not at the very end of the function? if (insertText !== undefined && !preferences.includeCompletionsWithInsertText) { return undefined; } @@ -685,7 +693,7 @@ namespace ts.Completions { // entries (like JavaScript identifier entries). return { name, - kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), // TODO: GH#18217 + kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), sortText, source: getSourceFromOrigin(origin), @@ -701,6 +709,58 @@ namespace ts.Completions { }; } + // >> TODO: Find better location for code + function isMethodOverrideCompletion(symbol: Symbol, location: Node): boolean { + return !!(symbol.flags & SymbolFlags.Method) && isPropertyDeclaration(location.parent); + // >> TODO: add more checks. e.g. the method suggestion could come from an interface the class implements, + // or some other possibilities? + } + + function getInsertTextForMethodOverrideCompletion(_typeChecker: TypeChecker, options: CompilerOptions, name: string, symbol: Symbol, location: Node) { + // const methodType = typeChecker.getTypeOfSymbolAtLocation(symbol, location); + // const signatures = methodType.getCallSignatures(); + const methodDeclarations = symbol.declarations?.filter(isMethodDeclaration); + // >> TODO: what should we do if we have more than 1 signature? when could that happen? + if (methodDeclarations?.length === 1) { + const originalDeclaration = methodDeclarations[0]; + const modifiers = originalDeclaration.modifiers?.filter(modifier => { + switch (modifier.kind) { // >> Simplify this if we only need to filter out "abstract" modifier. + case SyntaxKind.AbstractKeyword: + return false; + default: + return true; + } + }); + if (options.noImplicitOverride) { + modifiers?.push(factory.createModifier(SyntaxKind.OverrideKeyword)); + // Assuming it's ok if this modifier is duplicated. + } + + const completionDeclaration = factory.createMethodDeclaration( + /*decorators*/ undefined, // I'm guessing we don't want to deal with decorators? + /*modifiers*/ modifiers, + /*asteriskToken*/ originalDeclaration.asteriskToken, + /*name*/ name, + /*questionToken*/ originalDeclaration.questionToken, + /*typeParameters*/ originalDeclaration.typeParameters, + /*parameters*/ originalDeclaration.parameters, + /*type*/ originalDeclaration.type, + /*body*/ factory.createBlock([], /*multiLine*/ true)); + // const insertText = completionDeclaration.getText(location.getSourceFile()); + // const insertText = completionDeclaration.getText(); // Doesn't work with synthetic nodes + const printer = createPrinter({ + removeComments: true, + module: options.module, + target: options.target, + }); + const insertText = printer.printNode(EmitHint.Unspecified, completionDeclaration, location.getSourceFile()); + return { + insertText, + }; + } + return { }; + } + function originToCompletionEntryData(origin: SymbolOriginInfoExport): CompletionEntryData | undefined { return { exportName: origin.exportName, diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts new file mode 100644 index 0000000000000..75c1d6a66656e --- /dev/null +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -0,0 +1,36 @@ +/// + +////abstract class Base { +//// abstract foo(param1: string, param2: boolean): Promise; +////} +//// +////class Sub extends Base { +//// f/*a*/ +////} + + +verify.completions({ + marker: "a", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + }, + // exact: [ + + // ], + includes: [ + { + name: "foo", + isRecommended: true, + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + insertText: +`foo(param1: string, param2: boolean): Promise { +}`, + } + ], +}); From 2c84d88686ce637780ed20a370125b48f86d22f6 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 16 Sep 2021 17:15:43 -0700 Subject: [PATCH 02/38] WIP: start using codefix `addNewNodeForMemberSymbol` to create method decl node --- src/services/codefixes/helpers.ts | 13 +- src/services/completions.ts | 169 ++++++++++++------ .../fourslash/completionsOverridingMethod.ts | 9 +- 3 files changed, 132 insertions(+), 59 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index b734b8594783b..2d8f7236752a4 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -29,9 +29,18 @@ namespace ts.codefix { } /** - * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`. + * `addClassElement` will not be called if we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ - function addNewNodeForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, context: TypeConstructionContext, preferences: UserPreferences, importAdder: ImportAdder | undefined, addClassElement: (node: Node) => void): void { + export function addNewNodeForMemberSymbol( + symbol: Symbol, + enclosingDeclaration: ClassLikeDeclaration, + sourceFile: SourceFile, + context: TypeConstructionContext, + preferences: UserPreferences, + importAdder: ImportAdder | undefined, + // addClassElement: (node: ClassElement | FunctionExpression | ArrowFunction) => void, + addClassElement: (node: PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) => void, + ): void { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { return undefined; diff --git a/src/services/completions.ts b/src/services/completions.ts index c18ddff2cc59e..0cf3e6a39ccdc 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -273,7 +273,7 @@ namespace ts.Completions { switch (completionData.kind) { case CompletionDataKind.Data: - const response = completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, preferences); + const response = completionInfoFromData(sourceFile, host, program, compilerOptions, log, completionData, preferences); if (response?.isIncomplete) { incompleteCompletionsCache?.set(response); } @@ -387,7 +387,14 @@ namespace ts.Completions { return location?.kind === SyntaxKind.Identifier ? createTextSpanFromNode(location) : undefined; } - function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, preferences: UserPreferences): CompletionInfo | undefined { + function completionInfoFromData( + sourceFile: SourceFile, + host: LanguageServiceHost, + program: Program, + compilerOptions: CompilerOptions, + log: Log, completionData: CompletionData, + preferences: UserPreferences, + ): CompletionInfo | undefined { const { symbols, completionKind, @@ -425,7 +432,8 @@ namespace ts.Completions { /* contextToken */ undefined, location, sourceFile, - typeChecker, + host, + program, compilerOptions.target!, log, completionKind, @@ -453,7 +461,8 @@ namespace ts.Completions { /* contextToken */ undefined, location, sourceFile, - typeChecker, + host, + program, compilerOptions.target!, log, completionKind, @@ -594,7 +603,8 @@ namespace ts.Completions { contextToken: Node | undefined, location: Node, sourceFile: SourceFile, - typeChecker: TypeChecker, + host: LanguageServiceHost, + program: Program, name: string, needsConvertPropertyAccess: boolean, origin: SymbolOriginInfo | undefined, @@ -612,7 +622,9 @@ namespace ts.Completions { let isSnippet: true | undefined; let sourceDisplay; let hasAction; + let kindModifiers; + const typeChecker = program.getTypeChecker(); const insertQuestionDot = origin && originIsNullableMember(origin); const useBraces = origin && originIsSymbolMember(origin) || needsConvertPropertyAccess; if (origin && originIsThisType(origin)) { @@ -667,10 +679,8 @@ namespace ts.Completions { } if (isMethodOverrideCompletion(symbol, location)) { - ({ insertText } = getInsertTextForMethodOverrideCompletion(typeChecker, options, name, symbol, location)); - // replacementSpan = undefined; // >> TODO - isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined; - hasAction = true; + ({ insertText, isSnippet } = getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location)); + kindModifiers = SymbolDisplay.getSymbolModifiers(typeChecker, symbol); // >> TODO: remove `abstract` modifier from symbol? } // >> Should this actually be here and not at the very end of the function? @@ -694,7 +704,7 @@ namespace ts.Completions { return { name, kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), - kindModifiers: SymbolDisplay.getSymbolModifiers(typeChecker, symbol), + kindModifiers: kindModifiers || SymbolDisplay.getSymbolModifiers(typeChecker, symbol), sortText, source: getSourceFromOrigin(origin), hasAction: hasAction ? true : undefined, @@ -716,49 +726,97 @@ namespace ts.Completions { // or some other possibilities? } - function getInsertTextForMethodOverrideCompletion(_typeChecker: TypeChecker, options: CompilerOptions, name: string, symbol: Symbol, location: Node) { - // const methodType = typeChecker.getTypeOfSymbolAtLocation(symbol, location); - // const signatures = methodType.getCallSignatures(); - const methodDeclarations = symbol.declarations?.filter(isMethodDeclaration); - // >> TODO: what should we do if we have more than 1 signature? when could that happen? - if (methodDeclarations?.length === 1) { - const originalDeclaration = methodDeclarations[0]; - const modifiers = originalDeclaration.modifiers?.filter(modifier => { - switch (modifier.kind) { // >> Simplify this if we only need to filter out "abstract" modifier. - case SyntaxKind.AbstractKeyword: - return false; - default: - return true; - } - }); - if (options.noImplicitOverride) { - modifiers?.push(factory.createModifier(SyntaxKind.OverrideKeyword)); - // Assuming it's ok if this modifier is duplicated. - } - - const completionDeclaration = factory.createMethodDeclaration( - /*decorators*/ undefined, // I'm guessing we don't want to deal with decorators? - /*modifiers*/ modifiers, - /*asteriskToken*/ originalDeclaration.asteriskToken, - /*name*/ name, - /*questionToken*/ originalDeclaration.questionToken, - /*typeParameters*/ originalDeclaration.typeParameters, - /*parameters*/ originalDeclaration.parameters, - /*type*/ originalDeclaration.type, - /*body*/ factory.createBlock([], /*multiLine*/ true)); - // const insertText = completionDeclaration.getText(location.getSourceFile()); - // const insertText = completionDeclaration.getText(); // Doesn't work with synthetic nodes - const printer = createPrinter({ - removeComments: true, - module: options.module, - target: options.target, - }); - const insertText = printer.printNode(EmitHint.Unspecified, completionDeclaration, location.getSourceFile()); - return { - insertText, - }; + function getEntryForMemberCompletion( + host: LanguageServiceHost, + program: Program, + options: CompilerOptions, + preferences: UserPreferences, + name: string, + symbol: Symbol, + location: Node): { insertText: string, isSnippet?: true } { + const classLikeDeclaration = findAncestor(location, isClassLike); + if (!classLikeDeclaration) { + return { insertText: name }; } - return { }; + + let isSnippet: true | undefined; + let insertText: string = name; + const sourceFile = location.getSourceFile(); + const printer = createPrinter({ + removeComments: true, + module: options.module, + target: options.target, + omitTrailingSemicolon: true, + }); + const importAdder = codefix.createImportAdder(sourceFile, program, preferences, host); + codefix.addNewNodeForMemberSymbol( + symbol, + classLikeDeclaration, + sourceFile, + { program, host }, + preferences, + importAdder, + /* addClassElement */ nodeToEntry); + + + function nodeToEntry(node: PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction): void { + if (!isPropertyDeclaration(node) && node.body && isBlock(node.body)) { // Declaration has body, so we might need to transform this completion into a snippet. + factory.updateBlock(node.body, []); // TODO: add tabstop if editor supports snippets + if (preferences.includeCompletionsWithSnippetText) { + // TODO: add tabstop if editor supports snippets + isSnippet = true; + } + insertText = printer.printNode(EmitHint.Unspecified, node, sourceFile); + } + else { // Declaration has no body or body is not a block. + insertText = printer.printNode(EmitHint.Unspecified, node, sourceFile); + } + } + // ** ----- ** // + + // const methodDeclarations = symbol.declarations?.filter(isMethodDeclaration); + // // >> TODO: what should we do if we have more than 1 signature? when could that happen? + // if (methodDeclarations?.length === 1) { + // const originalDeclaration = methodDeclarations[0]; + // const modifiers = originalDeclaration.modifiers?.filter(modifier => { + // switch (modifier.kind) { // >> Simplify this if we only need to filter out "abstract" modifier. + // case SyntaxKind.AbstractKeyword: + // return false; + // default: + // return true; + // } + // }); + // if (options.noImplicitOverride) { + // modifiers?.push(factory.createModifier(SyntaxKind.OverrideKeyword)); + // // Assuming it's ok if this modifier is duplicated. + // } + + // const tabStop = preferences.includeCompletionsWithSnippetText ? "$1" : ""; + // const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier(tabStop)); + // const completionDeclaration = factory.createMethodDeclaration( + // /*decorators*/ undefined, // I'm guessing we don't want to deal with decorators? + // /*modifiers*/ modifiers, + // /*asteriskToken*/ originalDeclaration.asteriskToken, + // /*name*/ name, + // /*questionToken*/ originalDeclaration.questionToken, + // /*typeParameters*/ originalDeclaration.typeParameters, + // /*parameters*/ originalDeclaration.parameters, + // /*type*/ originalDeclaration.type, + // /*body*/ factory.createBlock([tabStopStatement], /*multiLine*/ true)); + + // const printer = createPrinter({ + // removeComments: true, + // module: options.module, + // target: options.target, + // omitTrailingSemicolon: true, + // }); + // const insertText = printer.printNode(EmitHint.Unspecified, completionDeclaration, location.getSourceFile()); + // return { + // insertText, + // isSnippet: preferences.includeCompletionsWithSnippetText ? true as const : undefined, + // }; + // } + return { insertText, isSnippet }; } function originToCompletionEntryData(origin: SymbolOriginInfoExport): CompletionEntryData | undefined { @@ -821,7 +879,8 @@ namespace ts.Completions { contextToken: Node | undefined, location: Node, sourceFile: SourceFile, - typeChecker: TypeChecker, + host: LanguageServiceHost, + program: Program, target: ScriptTarget, log: Log, kind: CompletionKind, @@ -839,6 +898,7 @@ namespace ts.Completions { const start = timestamp(); const variableDeclaration = getVariableDeclaration(location); const useSemicolons = probablyUsesSemicolons(sourceFile); + const typeChecker = program.getTypeChecker(); // Tracks unique names. // Value is set to false for global variables or completions from external module exports, because we can have multiple of those; // true otherwise. Based on the order we add things we will always see locals first, then globals, then module exports. @@ -861,7 +921,8 @@ namespace ts.Completions { contextToken, location, sourceFile, - typeChecker, + host, + program, name, needsConvertPropertyAccess, origin, diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index 75c1d6a66656e..28c101735a0d0 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -8,15 +8,19 @@ //// f/*a*/ ////} +// format.setFormatOptions({ +// newLineCharacter: "\n", +// }); +// format.setOption("newline", "\n"); verify.completions({ marker: "a", isNewIdentifierLocation: true, preferences: { includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, }, // exact: [ - // ], includes: [ { @@ -29,8 +33,7 @@ verify.completions({ end: 0, }, insertText: -`foo(param1: string, param2: boolean): Promise { -}`, +"foo(param1: string, param2: boolean): Promise {\r\n}", } ], }); From 4d2d4769625957951adc6b149db647b78cef37d5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 20 Sep 2021 11:39:07 -0700 Subject: [PATCH 03/38] update type of addNewNodeForMemberSymbol --- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- src/services/codefixes/helpers.ts | 14 ++++++++-- src/services/completions.ts | 3 +- src/services/stringCompletions.ts | 28 +++++++++++++++---- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 9e8313f357b14..8c317481e1d82 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -42,7 +42,7 @@ namespace ts.codefix { const abstractAndNonPrivateExtendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType).filter(symbolPointsToNonPrivateAndAbstractMember); const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host); - createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, sourceFile, context, preferences, importAdder, member => changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member)); + createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, sourceFile, context, preferences, importAdder, member => changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member as ClassElement)); // >> TODO. importAdder.writeFixes(changeTracker); } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index e1f17cb2856fc..f195721a6dae3 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -64,7 +64,7 @@ namespace ts.codefix { } const importAdder = createImportAdder(sourceFile, context.program, preferences, context.host); - createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, sourceFile, context, preferences, importAdder, member => insertInterfaceMemberNode(sourceFile, classDeclaration, member)); + createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, sourceFile, context, preferences, importAdder, member => insertInterfaceMemberNode(sourceFile, classDeclaration, member as ClassElement)); // >> TODO. importAdder.writeFixes(changeTracker); function createMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind): void { diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 2d8f7236752a4..6ed8aced97153 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -7,7 +7,14 @@ namespace ts.codefix { * @param importAdder If provided, type annotations will use identifier type references instead of ImportTypeNodes, and the missing imports will be added to the importAdder. * @returns Empty string iff there are no member insertions. */ - export function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: readonly Symbol[], sourceFile: SourceFile, context: TypeConstructionContext, preferences: UserPreferences, importAdder: ImportAdder | undefined, addClassElement: (node: ClassElement) => void): void { + export function createMissingMemberNodes( + classDeclaration: ClassLikeDeclaration, + possiblyMissingSymbols: readonly Symbol[], + sourceFile: SourceFile, + context: TypeConstructionContext, + preferences: UserPreferences, + importAdder: ImportAdder | undefined, + addClassElement: (node: AddNode) => void): void { const classMembers = classDeclaration.symbol.members!; for (const symbol of possiblyMissingSymbols) { if (!classMembers.has(symbol.escapedName)) { @@ -28,6 +35,8 @@ namespace ts.codefix { host: LanguageServiceHost; } + type AddNode = PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction; + /** * `addClassElement` will not be called if we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ @@ -38,8 +47,7 @@ namespace ts.codefix { context: TypeConstructionContext, preferences: UserPreferences, importAdder: ImportAdder | undefined, - // addClassElement: (node: ClassElement | FunctionExpression | ArrowFunction) => void, - addClassElement: (node: PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) => void, + addClassElement: (node: AddNode) => void, ): void { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { diff --git a/src/services/completions.ts b/src/services/completions.ts index 0cf3e6a39ccdc..795533cb7ba2f 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -243,7 +243,6 @@ namespace ts.Completions { // If the request is a continuation of an earlier `isIncomplete` response, // we can continue it from the cached previous response. - const typeChecker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); const incompleteCompletionsCache = preferences.allowIncompleteCompletions ? host.getIncompleteCompletionsCache?.() : undefined; if (incompleteCompletionsCache && completionKind === CompletionTriggerKind.TriggerForIncompleteCompletions && previousToken && isIdentifier(previousToken)) { @@ -256,7 +255,7 @@ namespace ts.Completions { incompleteCompletionsCache?.clear(); } - const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, typeChecker, compilerOptions, host, log, preferences); + const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, compilerOptions, host, program, log, preferences); if (stringCompletions) { return stringCompletions; } diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 8105a537a7664..9f53cf08a1ed1 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -1,18 +1,35 @@ /* @internal */ namespace ts.Completions.StringCompletions { - export function getStringLiteralCompletions(sourceFile: SourceFile, position: number, contextToken: Node | undefined, checker: TypeChecker, options: CompilerOptions, host: LanguageServiceHost, log: Log, preferences: UserPreferences): CompletionInfo | undefined { + export function getStringLiteralCompletions( + sourceFile: SourceFile, + position: number, + contextToken: Node | undefined, + options: CompilerOptions, + host: LanguageServiceHost, + program: Program, + log: Log, + preferences: UserPreferences): CompletionInfo | undefined { if (isInReferenceComment(sourceFile, position)) { const entries = getTripleSlashReferenceCompletion(sourceFile, position, options, host); return entries && convertPathCompletions(entries); } if (isInString(sourceFile, position, contextToken)) { if (!contextToken || !isStringLiteralLike(contextToken)) return undefined; - const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host, preferences); - return convertStringLiteralCompletions(entries, contextToken, sourceFile, checker, log, options, preferences); + const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, program.getTypeChecker(), options, host, preferences); + return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences); } } - function convertStringLiteralCompletions(completion: StringLiteralCompletion | undefined, contextToken: StringLiteralLike, sourceFile: SourceFile, checker: TypeChecker, log: Log, options: CompilerOptions, preferences: UserPreferences): CompletionInfo | undefined { + function convertStringLiteralCompletions( + completion: StringLiteralCompletion | undefined, + contextToken: StringLiteralLike, + sourceFile: SourceFile, + host: LanguageServiceHost, + program: Program, + log: Log, + options: CompilerOptions, + preferences: UserPreferences, + ): CompletionInfo | undefined { if (completion === undefined) { return undefined; } @@ -29,7 +46,8 @@ namespace ts.Completions.StringCompletions { contextToken, sourceFile, sourceFile, - checker, + host, + program, ScriptTarget.ESNext, log, CompletionKind.String, From c608a6eee960fc8d9d9205f80ef6baca6ce360d5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 20 Sep 2021 17:44:47 -0700 Subject: [PATCH 04/38] add more tests and support more cases --- src/services/codefixes/helpers.ts | 23 ++-- src/services/completions.ts | 96 ++++++-------- .../fourslash/completionsOverridingMethod.ts | 121 +++++++++++++++++- 3 files changed, 166 insertions(+), 74 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 6ed8aced97153..6fe8b12b5b363 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -18,7 +18,7 @@ namespace ts.codefix { const classMembers = classDeclaration.symbol.members!; for (const symbol of possiblyMissingSymbols) { if (!classMembers.has(symbol.escapedName)) { - addNewNodeForMemberSymbol(symbol, classDeclaration, sourceFile, context, preferences, importAdder, addClassElement); + addNewNodeForMemberSymbol(symbol, classDeclaration, sourceFile, context, preferences, importAdder, addClassElement, /* body */ undefined); } } } @@ -39,6 +39,7 @@ namespace ts.codefix { /** * `addClassElement` will not be called if we can't figure out a representation for `symbol` in `enclosingDeclaration`. + * @param body If defined, this will be the body of the member node passed to `addClassElement`. Otherwise, the body will default to a stub. */ export function addNewNodeForMemberSymbol( symbol: Symbol, @@ -48,6 +49,7 @@ namespace ts.codefix { preferences: UserPreferences, importAdder: ImportAdder | undefined, addClassElement: (node: AddNode) => void, + body: Block | undefined, ): void { const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { @@ -106,7 +108,7 @@ namespace ts.codefix { name, emptyArray, typeNode, - ambient ? undefined : createStubbedMethodBody(quotePreference))); + ambient ? undefined : body || createStubbedMethodBody(quotePreference))); } else { Debug.assertNode(accessor, isSetAccessorDeclaration, "The counterpart to a getter should be a setter"); @@ -117,7 +119,7 @@ namespace ts.codefix { modifiers, name, createDummyParameters(1, [parameterName], [typeNode], 1, /*inJs*/ false), - ambient ? undefined : createStubbedMethodBody(quotePreference))); + ambient ? undefined : body || createStubbedMethodBody(quotePreference))); } } break; @@ -139,7 +141,7 @@ namespace ts.codefix { if (declarations.length === 1) { Debug.assert(signatures.length === 1, "One declaration implies one signature"); const signature = signatures[0]; - outputMethod(quotePreference, signature, modifiers, name, ambient ? undefined : createStubbedMethodBody(quotePreference)); + outputMethod(quotePreference, signature, modifiers, name, ambient ? undefined : body || createStubbedMethodBody(quotePreference)); break; } @@ -151,11 +153,11 @@ namespace ts.codefix { if (!ambient) { if (declarations.length > signatures.length) { const signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1] as SignatureDeclaration)!; - outputMethod(quotePreference, signature, modifiers, name, createStubbedMethodBody(quotePreference)); + outputMethod(quotePreference, signature, modifiers, name, body || createStubbedMethodBody(quotePreference)); } else { Debug.assert(declarations.length === signatures.length, "Declarations and signatures should match count"); - addClassElement(createMethodImplementingSignatures(checker, context, enclosingDeclaration, signatures, name, optional, modifiers, quotePreference)); + addClassElement(createMethodImplementingSignatures(checker, context, enclosingDeclaration, signatures, name, optional, modifiers, quotePreference, body)); } } break; @@ -365,6 +367,7 @@ namespace ts.codefix { optional: boolean, modifiers: readonly Modifier[] | undefined, quotePreference: QuotePreference, + body: Block | undefined, ): MethodDeclaration { /** This is *a* signature with the maximal number of arguments, * such that if there is a "maximal" signature without rest arguments, @@ -406,7 +409,8 @@ namespace ts.codefix { /*typeParameters*/ undefined, parameters, getReturnTypeFromSignatures(signatures, checker, context, enclosingDeclaration), - quotePreference); + quotePreference, + body); } function getReturnTypeFromSignatures(signatures: readonly Signature[], checker: TypeChecker, context: TypeConstructionContext, enclosingDeclaration: ClassLikeDeclaration): TypeNode | undefined { @@ -423,7 +427,8 @@ namespace ts.codefix { typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], returnType: TypeNode | undefined, - quotePreference: QuotePreference + quotePreference: QuotePreference, + body: Block | undefined ): MethodDeclaration { return factory.createMethodDeclaration( /*decorators*/ undefined, @@ -434,7 +439,7 @@ namespace ts.codefix { typeParameters, parameters, returnType, - createStubbedMethodBody(quotePreference)); + body || createStubbedMethodBody(quotePreference)); } function createStubbedMethodBody(quotePreference: QuotePreference) { diff --git a/src/services/completions.ts b/src/services/completions.ts index 795533cb7ba2f..d88e59d26b8a0 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -391,7 +391,8 @@ namespace ts.Completions { host: LanguageServiceHost, program: Program, compilerOptions: CompilerOptions, - log: Log, completionData: CompletionData, + log: Log, + completionData: CompletionData, preferences: UserPreferences, ): CompletionInfo | undefined { const { @@ -719,6 +720,7 @@ namespace ts.Completions { } // >> TODO: Find better location for code + // >> TODO: update this to `isMemberCompletion`... ? function isMethodOverrideCompletion(symbol: Symbol, location: Node): boolean { return !!(symbol.flags & SymbolFlags.Method) && isPropertyDeclaration(location.parent); // >> TODO: add more checks. e.g. the method suggestion could come from an interface the class implements, @@ -748,6 +750,14 @@ namespace ts.Completions { omitTrailingSemicolon: true, }); const importAdder = codefix.createImportAdder(sourceFile, program, preferences, host); + let body; + if (preferences.includeCompletionsWithSnippetText) { + isSnippet = true; + body = factory.createBlock([], /* multiline */ true); // TODO: add tabstop + } + else { + body = factory.createBlock([], /* multiline */ true); + } codefix.addNewNodeForMemberSymbol( symbol, classLikeDeclaration, @@ -755,66 +765,34 @@ namespace ts.Completions { { program, host }, preferences, importAdder, - /* addClassElement */ nodeToEntry); - - - function nodeToEntry(node: PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction): void { - if (!isPropertyDeclaration(node) && node.body && isBlock(node.body)) { // Declaration has body, so we might need to transform this completion into a snippet. - factory.updateBlock(node.body, []); // TODO: add tabstop if editor supports snippets - if (preferences.includeCompletionsWithSnippetText) { - // TODO: add tabstop if editor supports snippets - isSnippet = true; + node => { + if (isClassDeclaration(classLikeDeclaration) && hasAbstractModifier(classLikeDeclaration)) { + // Add `abstract` modifier + node = factory.updateModifiers( + node, + concatenate([factory.createModifier(SyntaxKind.AbstractKeyword)], node.modifiers), + ); + if (isMethodDeclaration(node)) { + // Remove method body + // >> TODO: maybe move this up, when creating the body above? + node = factory.updateMethodDeclaration( + node, + node.decorators, + node.modifiers, + node.asteriskToken, + node.name, + node.questionToken, + node.typeParameters, + node.parameters, + node.type, + /* body */ undefined, + ); + } } insertText = printer.printNode(EmitHint.Unspecified, node, sourceFile); - } - else { // Declaration has no body or body is not a block. - insertText = printer.printNode(EmitHint.Unspecified, node, sourceFile); - } - } - // ** ----- ** // - - // const methodDeclarations = symbol.declarations?.filter(isMethodDeclaration); - // // >> TODO: what should we do if we have more than 1 signature? when could that happen? - // if (methodDeclarations?.length === 1) { - // const originalDeclaration = methodDeclarations[0]; - // const modifiers = originalDeclaration.modifiers?.filter(modifier => { - // switch (modifier.kind) { // >> Simplify this if we only need to filter out "abstract" modifier. - // case SyntaxKind.AbstractKeyword: - // return false; - // default: - // return true; - // } - // }); - // if (options.noImplicitOverride) { - // modifiers?.push(factory.createModifier(SyntaxKind.OverrideKeyword)); - // // Assuming it's ok if this modifier is duplicated. - // } - - // const tabStop = preferences.includeCompletionsWithSnippetText ? "$1" : ""; - // const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier(tabStop)); - // const completionDeclaration = factory.createMethodDeclaration( - // /*decorators*/ undefined, // I'm guessing we don't want to deal with decorators? - // /*modifiers*/ modifiers, - // /*asteriskToken*/ originalDeclaration.asteriskToken, - // /*name*/ name, - // /*questionToken*/ originalDeclaration.questionToken, - // /*typeParameters*/ originalDeclaration.typeParameters, - // /*parameters*/ originalDeclaration.parameters, - // /*type*/ originalDeclaration.type, - // /*body*/ factory.createBlock([tabStopStatement], /*multiLine*/ true)); - - // const printer = createPrinter({ - // removeComments: true, - // module: options.module, - // target: options.target, - // omitTrailingSemicolon: true, - // }); - // const insertText = printer.printNode(EmitHint.Unspecified, completionDeclaration, location.getSourceFile()); - // return { - // insertText, - // isSnippet: preferences.includeCompletionsWithSnippetText ? true as const : undefined, - // }; - // } + }, + body); + return { insertText, isSnippet }; } diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index 28c101735a0d0..ca4717ea70e11 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -1,11 +1,53 @@ /// -////abstract class Base { +// @Filename: a.ts +// Case: Concrete class implements abstract method +////abstract class ABase { //// abstract foo(param1: string, param2: boolean): Promise; ////} //// -////class Sub extends Base { -//// f/*a*/ +////class ASub extends ABase { +//// f/*a*/ +////} + +// @Filename: b.ts +// Case: Concrete class overrides concrete method +////class BBase { +//// foo(a: string, b: string): string { +//// return a + b; +//// } +////} +//// +////class BSub extends BBase { +//// f/*b*/ +////} + +// @Filename: c.ts +// Case: Multiple overrides, concrete class overrides concrete method +////class CBase { +//// foo(a: string | number): string { +//// return a + ""; +//// } +////} +//// +////class CSub extends CBase { +//// foo(a: string): string { +//// return add; +//// } +////} +//// +////class CSub2 extends CSub { +//// f/*c*/ +////} + +// @Filename: d.ts +// Case: Abstract class extends abstract class +////abstract class DBase { +//// abstract foo(a: string): string; +////} +//// +////abstract class DSub extends DBase { +//// f/*d*/ ////} // format.setFormatOptions({ @@ -20,20 +62,87 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: true, }, - // exact: [ - // ], includes: [ { name: "foo", - isRecommended: true, sortText: completion.SortText.LocationPriority, replacementSpan: { fileName: "", pos: 0, end: 0, }, + isSnippet: true, insertText: "foo(param1: string, param2: boolean): Promise {\r\n}", } ], }); + +verify.completions({ + marker: "b", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"foo(a: string, b: string): string {\r\n}", + } + ], +}); + +verify.completions({ + marker: "c", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"foo(a: string): string {\r\n}", + } + ], +}); + +verify.completions({ + marker: "d", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"abstract foo(a: string): string;", // Currently fails because no trailing semicolon + } + ], +}); \ No newline at end of file From 2fa43e85312597be09745476f596db7697337e82 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 21 Sep 2021 18:48:36 -0700 Subject: [PATCH 05/38] add more tests and fix some details --- src/services/completions.ts | 36 ++++-- .../fourslash/completionsOverridingMethod.ts | 110 +++++++++++++++++- 2 files changed, 133 insertions(+), 13 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index d88e59d26b8a0..246aaa729e42c 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -678,7 +678,7 @@ namespace ts.Completions { } } - if (isMethodOverrideCompletion(symbol, location)) { + if (isClassLikeMemberCompletion(symbol, location)) { ({ insertText, isSnippet } = getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location)); kindModifiers = SymbolDisplay.getSymbolModifiers(typeChecker, symbol); // >> TODO: remove `abstract` modifier from symbol? } @@ -720,11 +720,15 @@ namespace ts.Completions { } // >> TODO: Find better location for code - // >> TODO: update this to `isMemberCompletion`... ? - function isMethodOverrideCompletion(symbol: Symbol, location: Node): boolean { - return !!(symbol.flags & SymbolFlags.Method) && isPropertyDeclaration(location.parent); - // >> TODO: add more checks. e.g. the method suggestion could come from an interface the class implements, - // or some other possibilities? + function isClassLikeMemberCompletion(symbol: Symbol, location: Node): boolean { + const memberFlags = + // SymbolFlags.Method + // | SymbolFlags.Accessor + // | SymbolFlags.Property + SymbolFlags.ClassMember + & SymbolFlags.EnumMemberExcludes; + // >> TODO: Flags: Constructor? Signature? + return !!findAncestor(location, isClassLike) && !!(symbol.flags & memberFlags); } function getEntryForMemberCompletion( @@ -753,11 +757,14 @@ namespace ts.Completions { let body; if (preferences.includeCompletionsWithSnippetText) { isSnippet = true; - body = factory.createBlock([], /* multiline */ true); // TODO: add tabstop + const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier("$1")); + body = factory.createBlock([tabStopStatement], /* multiline */ true); } else { body = factory.createBlock([], /* multiline */ true); } + + const completionNodes: Node[] = []; codefix.addNewNodeForMemberSymbol( symbol, classLikeDeclaration, @@ -766,15 +773,23 @@ namespace ts.Completions { preferences, importAdder, node => { + // `addNewNodeForMemberSymbol` calls this callback function for each new member node + // it adds for the given member symbol. + // We store these member nodes in the `completionNodes` array. + // Note that there might be: + // - No nodes if `addNewNodeForMemberSymbol` cannot figure out a node for the member; + // - One node; + // - More than one node if the member is overloaded (e.g. a method with overload signatures). if (isClassDeclaration(classLikeDeclaration) && hasAbstractModifier(classLikeDeclaration)) { // Add `abstract` modifier node = factory.updateModifiers( node, concatenate([factory.createModifier(SyntaxKind.AbstractKeyword)], node.modifiers), ); + // >> TODO: we want to remove the body in more cases I think + // >> e.g. interfaces? if (isMethodDeclaration(node)) { // Remove method body - // >> TODO: maybe move this up, when creating the body above? node = factory.updateMethodDeclaration( node, node.decorators, @@ -789,10 +804,13 @@ namespace ts.Completions { ); } } - insertText = printer.printNode(EmitHint.Unspecified, node, sourceFile); + completionNodes.push(node); }, body); + if (completionNodes.length) { + insertText = printer.printList(ListFormat.MultiLine, factory.createNodeArray(completionNodes), sourceFile); + } return { insertText, isSnippet }; } diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index ca4717ea70e11..e99153e3112f0 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -50,6 +50,37 @@ //// f/*d*/ ////} +// @Filename: e.ts +// Case: Class implements interface +////interface EBase { +//// foo(a: string): string; +////} +//// +////class ESub implements EBase { +//// f/*e*/ +////} + +// @Filename: f.ts +// Case: Abstract class implements interface +////interface FBase { +//// foo(a: string): string; +////} +//// +////abstract class FSub implements FBase { +//// f/*f*/ +////} + +// @Filename: g.ts +// Case: Method has overloads +////interface GBase { +//// foo(a: string): string; +//// foo(a: undefined, b: number): string; +////} +//// +////class GSub implements GBase { +//// f/*g*/ +////} + // format.setFormatOptions({ // newLineCharacter: "\n", // }); @@ -73,7 +104,7 @@ verify.completions({ }, isSnippet: true, insertText: -"foo(param1: string, param2: boolean): Promise {\r\n}", +"foo(param1: string, param2: boolean): Promise {\r\n $1;\r\n}\r\n", } ], }); @@ -96,7 +127,7 @@ verify.completions({ }, isSnippet: true, insertText: -"foo(a: string, b: string): string {\r\n}", +"foo(a: string, b: string): string {\r\n $1;\r\n}\r\n", } ], }); @@ -119,7 +150,7 @@ verify.completions({ }, isSnippet: true, insertText: -"foo(a: string): string {\r\n}", +"foo(a: string): string {\r\n $1;\r\n}\r\n", } ], }); @@ -142,7 +173,78 @@ verify.completions({ }, isSnippet: true, insertText: -"abstract foo(a: string): string;", // Currently fails because no trailing semicolon +"abstract foo(a: string): string;\r\n", + } + ], +}); + +verify.completions({ + marker: "e", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"foo(a: string): string {\r\n $1;\r\n}\r\n", + } + ], +}); + +verify.completions({ + marker: "f", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"abstract foo(a: string): string;\r\n", + } + ], +}); + +verify.completions({ + marker: "g", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"foo(a: string): string;\r\n\ +foo(a: undefined, b: number): string;\r\n\ +foo(a: any, b?: any): string {\r\n $1;\r\n}\r\n", } ], }); \ No newline at end of file From 1d04720a9bbf16fec935aeedc6584c7180a38292 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 23 Sep 2021 12:22:00 -0700 Subject: [PATCH 06/38] wip: more fixes and tests --- src/services/completions.ts | 57 ++++++++++--------- .../fourslash/completionsOverridingMethod.ts | 7 ++- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 246aaa729e42c..700b1e0fe4208 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -772,37 +772,42 @@ namespace ts.Completions { { program, host }, preferences, importAdder, + // `addNewNodeForMemberSymbol` calls this callback function for each new member node + // it adds for the given member symbol. + // We store these member nodes in the `completionNodes` array. + // Note that there might be: + // - No nodes if `addNewNodeForMemberSymbol` cannot figure out a node for the member; + // - One node; + // - More than one node if the member is overloaded (e.g. a method with overload signatures). node => { - // `addNewNodeForMemberSymbol` calls this callback function for each new member node - // it adds for the given member symbol. - // We store these member nodes in the `completionNodes` array. - // Note that there might be: - // - No nodes if `addNewNodeForMemberSymbol` cannot figure out a node for the member; - // - One node; - // - More than one node if the member is overloaded (e.g. a method with overload signatures). - if (isClassDeclaration(classLikeDeclaration) && hasAbstractModifier(classLikeDeclaration)) { + // >> TODO: making it abstract. might not need it after all. + // if (hasAbstractModifier(classLikeDeclaration)) { // Add `abstract` modifier + // node = factory.updateModifiers( + // node, + // concatenate([factory.createModifier(SyntaxKind.AbstractKeyword)], node.modifiers), + // ); + // if (isMethodDeclaration(node)) { + // // Remove method body + // node = factory.updateMethodDeclaration( + // node, + // node.decorators, + // node.modifiers, + // node.asteriskToken, + // node.name, + // node.questionToken, + // node.typeParameters, + // node.parameters, + // node.type, + // /* body */ undefined, + // ); + // } + // } + if (options.noImplicitOverride && /* TODO: isOverride(node) */ undefined) { node = factory.updateModifiers( node, - concatenate([factory.createModifier(SyntaxKind.AbstractKeyword)], node.modifiers), + concatenate([factory.createModifier(SyntaxKind.OverrideKeyword)], node.modifiers), ); - // >> TODO: we want to remove the body in more cases I think - // >> e.g. interfaces? - if (isMethodDeclaration(node)) { - // Remove method body - node = factory.updateMethodDeclaration( - node, - node.decorators, - node.modifiers, - node.asteriskToken, - node.name, - node.questionToken, - node.typeParameters, - node.parameters, - node.type, - /* body */ undefined, - ); - } } completionNodes.push(node); }, diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index e99153e3112f0..289b3af378328 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -173,7 +173,7 @@ verify.completions({ }, isSnippet: true, insertText: -"abstract foo(a: string): string;\r\n", +"foo(a: string): string {\r\n $1;\r\n}\r\n", } ], }); @@ -219,7 +219,7 @@ verify.completions({ }, isSnippet: true, insertText: -"abstract foo(a: string): string;\r\n", +"foo(a: string): string {\r\n $1;\r\n}\r\n", } ], }); @@ -247,4 +247,5 @@ foo(a: undefined, b: number): string;\r\n\ foo(a: any, b?: any): string {\r\n $1;\r\n}\r\n", } ], -}); \ No newline at end of file +}); + From 905caad677422399f769e32a76e49feb02f9cc74 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 23 Sep 2021 15:02:32 -0700 Subject: [PATCH 07/38] expose check override modifier in checker --- src/compiler/checker.ts | 196 +++++++++++++++--- src/compiler/types.ts | 8 + src/services/completions.ts | 6 +- .../fourslash/completionsOverridingMethod.ts | 33 +++ 4 files changed, 208 insertions(+), 35 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b71cfe8f3e97a..6c47db65622e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -720,6 +720,7 @@ namespace ts { getLocalTypeParametersOfClassOrInterfaceOrTypeAlias, isDeclarationVisible, isPropertyAccessible, + getMemberOverrideModifierDiagnostic, }; function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined { @@ -37781,7 +37782,7 @@ namespace ts { } } - checkMembersForMissingOverrideModifier(node, type, typeWithThis, staticType); + checkMembersForOverrideModifier(node, type, typeWithThis, staticType); const implementedTypeNodes = getEffectiveImplementsTypeNodes(node); if (implementedTypeNodes) { @@ -37818,8 +37819,7 @@ namespace ts { } } - function checkMembersForMissingOverrideModifier(node: ClassLikeDeclaration, type: InterfaceType, typeWithThis: Type, staticType: ObjectType) { - const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); + function checkMembersForOverrideModifier(node: ClassLikeDeclaration, type: InterfaceType, typeWithThis: Type, staticType: ObjectType) { const baseTypeNode = getEffectiveBaseTypeNode(node); const baseTypes = baseTypeNode && getBaseTypes(type); const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(first(baseTypes), type.thisType) : undefined; @@ -37833,56 +37833,142 @@ namespace ts { if (isConstructorDeclaration(member)) { forEach(member.parameters, param => { if (isParameterPropertyDeclaration(param, member)) { - checkClassMember(param, /*memberIsParameterProperty*/ true); + checkExistingMemberForOverrideModifier( + node, + staticType, + baseStaticType, + baseWithThis, + type, + typeWithThis, + param, + /* memberIsParameterProperty */ true + ); } }); } - checkClassMember(member); + checkExistingMemberForOverrideModifier( + node, + staticType, + baseStaticType, + baseWithThis, + type, + typeWithThis, + member, + /* memberIsParameterProperty */ false, + ); } + } - function checkClassMember(member: ClassElement | ParameterPropertyDeclaration, memberIsParameterProperty?: boolean) { - const hasOverride = hasOverrideModifier(member); - const hasStatic = isStatic(member); - if (baseWithThis && (hasOverride || compilerOptions.noImplicitOverride)) { - const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member); - if (!declaredProp) { - return; - } - - const thisType = hasStatic ? staticType : typeWithThis; - const baseType = hasStatic ? baseStaticType : baseWithThis; - const prop = getPropertyOfType(thisType, declaredProp.escapedName); - const baseProp = getPropertyOfType(baseType, declaredProp.escapedName); + /** + * @param member Existing member node to be checked. + * Note: `member` cannot be a synthetic node. + */ + function checkExistingMemberForOverrideModifier( + node: ClassLikeDeclaration, + staticType: ObjectType, + baseStaticType: Type, + baseWithThis: Type | undefined, + type: InterfaceType, + typeWithThis: Type, + member: ClassElement | ParameterPropertyDeclaration, + memberIsParameterProperty: boolean, + reportErrors = true, + ): MemberOverrideDiagnostic { + const declaredProp = member.name + && getSymbolAtLocation(member.name) + || getSymbolAtLocation(member); + if (!declaredProp) { + return MemberOverrideDiagnostic.Ok; + } + + return checkMemberForOverrideModifier( + node, + staticType, + baseStaticType, + baseWithThis, + type, + typeWithThis, + hasOverrideModifier(member), + hasAbstractModifier(member), + isStatic(member), + memberIsParameterProperty, + symbolName(declaredProp), + reportErrors ? member : undefined, + ); + } - const baseClassName = typeToString(baseWithThis); - if (prop && !baseProp && hasOverride) { - const suggestion = getSuggestedSymbolForNonexistentClassMember(symbolName(declaredProp), baseType); + /** + * Checks a class member declaration for either a missing or an invalid `override` modifier. + * Note: this function can be used for speculative checking, + * i.e. checking a member that does not yet exist in the program. + * An example of that would be to call this function in a completions scenario, + * when offering a method declaration as completion. + * @param errorNode The node where we should report an error, or undefined if we should not report errors. + */ + function checkMemberForOverrideModifier( + node: ClassLikeDeclaration, + staticType: ObjectType, + baseStaticType: Type, + baseWithThis: Type | undefined, + type: InterfaceType, + typeWithThis: Type, + memberHasOverrideModifier: boolean, // >> Note: we need this because this is computed from a node, but we don't have any (it would be synthetic) + memberHasAbstractModifier: boolean, + memberIsStatic: boolean, + memberIsParameterProperty: boolean, + memberName: string, + errorNode?: Node, + ): MemberOverrideDiagnostic { + const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); + if (baseWithThis && (memberHasOverrideModifier || compilerOptions.noImplicitOverride)) { + const memberEscapedName = escapeLeadingUnderscores(memberName); + const thisType = memberIsStatic ? staticType : typeWithThis; + const baseType = memberIsStatic ? baseStaticType : baseWithThis; + const prop = getPropertyOfType(thisType, memberEscapedName); + const baseProp = getPropertyOfType(baseType, memberEscapedName); + + const baseClassName = typeToString(baseWithThis); + if (prop && !baseProp && memberHasOverrideModifier) { + if (errorNode) { + const suggestion = getSuggestedSymbolForNonexistentClassMember(memberName, baseType); // Again, using symbol name: note that's different from `symbol.escapedName` suggestion ? - error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) : - error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); + error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) : + error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); + } + return MemberOverrideDiagnostic.HasInvalidOverride; + } + else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) { + const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier); + if (memberHasOverrideModifier) { + return MemberOverrideDiagnostic.Ok; } - else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) { - const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier); - if (hasOverride) { - return; - } - if (!baseHasAbstract) { + if (!baseHasAbstract) { + if (errorNode) { const diag = memberIsParameterProperty ? Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 : Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0; - error(member, diag, baseClassName); + error(errorNode, diag, baseClassName); } - else if (hasAbstractModifier(member) && baseHasAbstract) { - error(member, Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0, baseClassName); + return MemberOverrideDiagnostic.NeedsOverride; + } + else if (memberHasAbstractModifier && baseHasAbstract) { + if (errorNode) { + error(errorNode, Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0, baseClassName); } + return MemberOverrideDiagnostic.NeedsOverride; } } - else if (hasOverride) { + } + else if (memberHasOverrideModifier) { + if (errorNode) { const className = typeToString(type); - error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, className); + error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, className); } + return MemberOverrideDiagnostic.HasInvalidOverride; } + + return MemberOverrideDiagnostic.Ok; } function issueMemberSpecificError(node: ClassLikeDeclaration, typeWithThis: Type, baseWithThis: Type, broadDiag: DiagnosticMessage) { @@ -37929,6 +38015,48 @@ namespace ts { } } + /** + * Checks a member declaration node to see if has a missing or invalid `override` modifier. + * @param node Class-like node where the member is declared. + * @param member Member declaration node. + * Note: `member` can be a synthetic node without a parent. + */ + function getMemberOverrideModifierDiagnostic(node: ClassLikeDeclaration, member: ClassElement): MemberOverrideDiagnostic { + if (!member.name) { + return MemberOverrideDiagnostic.Ok; + } + + const symbol = getSymbolOfNode(node); + const type = getDeclaredTypeOfSymbol(symbol) as InterfaceType; + const typeWithThis = getTypeWithThisArgument(type); + const staticType = getTypeOfSymbol(symbol) as ObjectType; + + const baseTypeNode = getEffectiveBaseTypeNode(node); + const baseTypes = baseTypeNode && getBaseTypes(type); + const baseWithThis = baseTypes?.length ? getTypeWithThisArgument(first(baseTypes), type.thisType) : undefined; + const baseStaticType = getBaseConstructorTypeOfClass(type); + + const memberHasOverrideModifier = member.parent + ? hasOverrideModifier(member) + : hasSyntacticModifier(member, ModifierFlags.Override); + + const memberName = unescapeLeadingUnderscores(getTextOfPropertyName(member.name)); + + return checkMemberForOverrideModifier( + node, + staticType, + baseStaticType, + baseWithThis, + type, + typeWithThis, + memberHasOverrideModifier, + hasAbstractModifier(member), + isStatic(member), + /* memberIsParameterProperty */ false, + memberName, + ); + } + function getTargetSymbol(s: Symbol) { // if symbol is instantiated its flags are not copied from the 'target' // so we'll need to get back original 'target' symbol to work with correct set of flags diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 08efc5d545797..3c46e680571a0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4363,6 +4363,14 @@ namespace ts { /* @internal */ getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): readonly TypeParameter[] | undefined; /* @internal */ isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; /* @internal */ isPropertyAccessible(node: Node, isSuper: boolean, isWrite: boolean, containingType: Type, property: Symbol): boolean; + /* @internal */ getMemberOverrideModifierDiagnostic(node: ClassLikeDeclaration, member: ClassElement): MemberOverrideDiagnostic; + } + + /* @internal */ + export const enum MemberOverrideDiagnostic { + Ok, + NeedsOverride, + HasInvalidOverride } /* @internal */ diff --git a/src/services/completions.ts b/src/services/completions.ts index 700b1e0fe4208..c1ba3f4045aca 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -746,6 +746,8 @@ namespace ts.Completions { let isSnippet: true | undefined; let insertText: string = name; + + const checker = program.getTypeChecker(); const sourceFile = location.getSourceFile(); const printer = createPrinter({ removeComments: true, @@ -754,6 +756,7 @@ namespace ts.Completions { omitTrailingSemicolon: true, }); const importAdder = codefix.createImportAdder(sourceFile, program, preferences, host); + let body; if (preferences.includeCompletionsWithSnippetText) { isSnippet = true; @@ -803,7 +806,8 @@ namespace ts.Completions { // ); // } // } - if (options.noImplicitOverride && /* TODO: isOverride(node) */ undefined) { + if (isClassElement(node) + && checker.getMemberOverrideModifierDiagnostic(classLikeDeclaration, node) === MemberOverrideDiagnostic.NeedsOverride) { node = factory.updateModifiers( node, concatenate([factory.createModifier(SyntaxKind.OverrideKeyword)], node.modifiers), diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index 289b3af378328..3df65b736b492 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -81,6 +81,17 @@ //// f/*g*/ ////} +// @Filename: h.ts +// @noImplicitOverride: true // >> TODO: move this to a new test file, because this option is global +// Case: Suggested method needs `override` modifier +////class HBase { +//// foo(a: string): void {} +////} +//// +////class HSub extends HBase { +//// f/*h*/ +////} + // format.setFormatOptions({ // newLineCharacter: "\n", // }); @@ -249,3 +260,25 @@ foo(a: any, b?: any): string {\r\n $1;\r\n}\r\n", ], }); +verify.completions({ + marker: "h", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"override foo(): void {\r\n $1;\r\n}\r\n", + } + ], +}); \ No newline at end of file From 8ad404270ce10736b87696c9841ec5ab23e5b420 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 30 Sep 2021 10:35:40 -0700 Subject: [PATCH 08/38] fix test --- .../fourslash/completionsOverridingMethod.ts | 34 ---------------- .../fourslash/completionsOverridingMethod1.ts | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 34 deletions(-) create mode 100644 tests/cases/fourslash/completionsOverridingMethod1.ts diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod.ts index 3df65b736b492..0097a44c40295 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod.ts @@ -81,17 +81,6 @@ //// f/*g*/ ////} -// @Filename: h.ts -// @noImplicitOverride: true // >> TODO: move this to a new test file, because this option is global -// Case: Suggested method needs `override` modifier -////class HBase { -//// foo(a: string): void {} -////} -//// -////class HSub extends HBase { -//// f/*h*/ -////} - // format.setFormatOptions({ // newLineCharacter: "\n", // }); @@ -258,27 +247,4 @@ foo(a: undefined, b: number): string;\r\n\ foo(a: any, b?: any): string {\r\n $1;\r\n}\r\n", } ], -}); - -verify.completions({ - marker: "h", - isNewIdentifierLocation: true, - preferences: { - includeCompletionsWithInsertText: true, - includeCompletionsWithSnippetText: true, - }, - includes: [ - { - name: "foo", - sortText: completion.SortText.LocationPriority, - replacementSpan: { - fileName: "", - pos: 0, - end: 0, - }, - isSnippet: true, - insertText: -"override foo(): void {\r\n $1;\r\n}\r\n", - } - ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod1.ts b/tests/cases/fourslash/completionsOverridingMethod1.ts new file mode 100644 index 0000000000000..3377ac5c7422c --- /dev/null +++ b/tests/cases/fourslash/completionsOverridingMethod1.ts @@ -0,0 +1,40 @@ +/// + +// @Filename: h.ts +// @noImplicitOverride: true +// Case: Suggested method needs `override` modifier +////class HBase { +//// foo(a: string): void {} +////} +//// +////class HSub extends HBase { +//// f/*h*/ +////} + +// format.setFormatOptions({ +// newLineCharacter: "\n", +// }); +// format.setOption("newline", "\n"); + +verify.completions({ + marker: "h", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + replacementSpan: { + fileName: "", + pos: 0, + end: 0, + }, + isSnippet: true, + insertText: +"override foo(a: string): void {\r\n $1;\r\n}\r\n", + } + ], +}); \ No newline at end of file From d20eb6852aa7ae2fb244e732fe19b4ed6937b6bc Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 30 Sep 2021 17:26:14 -0700 Subject: [PATCH 09/38] WIP: add snippet support --- src/compiler/types.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3c46e680571a0..0888e8807292f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6737,6 +6737,29 @@ namespace ts { externalHelpers?: boolean; helpers?: EmitHelper[]; // Emit helpers for the node startsOnNewLine?: boolean; // If the node should begin on a new line + snippetElement?: SnippetElement; // Snippet element of the node + } + + export interface SnippetElement { + kind: SnippetKind; + } + + export interface TabStop extends SnippetElement { + kind: SnippetKind.TabStop; + order: number; + } + + export interface PlaceHolder extends SnippetElement { + kind: SnippetKind.Placeholder; + order: number; + } + + // Reference: https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax + export const enum SnippetKind { + TabStop, // `$1`, `$2` + Placeholder, // `${1:foo}` + Choice, // `${1|one,two,three|}` + Variable, // `$name`, `${name:default}` } export const enum EmitFlags { From c81f3856be87df3c6de3992e324d820f706ac25a Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 4 Oct 2021 18:13:16 -0700 Subject: [PATCH 10/38] WIP: snippet support on emitter, adding snippets in completions --- src/compiler/debug.ts | 4 ++++ src/compiler/emitter.ts | 32 +++++++++++++++++++++++++++++- src/compiler/factory/emitNode.ts | 16 +++++++++++++++ src/compiler/types.ts | 8 +++----- src/compiler/utilities.ts | 4 ++-- src/services/completions.ts | 34 ++++++++++++++++++++++++++++++-- src/services/snippets.ts | 23 +++++++++++++++++++++ src/services/tsconfig.json | 1 + 8 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 src/services/snippets.ts diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 2e6b87a30e646..705ab949899bd 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -351,6 +351,10 @@ namespace ts { return formatEnum(kind, (ts as any).SyntaxKind, /*isFlags*/ false); } + export function formatSnippetKind(kind: SnippetKind | undefined): string { + return formatEnum(kind, (ts as any).SnippetKind, /*isFlags*/ false); + } + export function formatNodeFlags(flags: NodeFlags | undefined): string { return formatEnum(flags, (ts as any).NodeFlags, /*isFlags*/ true); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5667e792b4606..5c9aaf23c1180 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1302,7 +1302,13 @@ namespace ts { currentParenthesizerRule = undefined; } - function pipelineEmitWithHintWorker(hint: EmitHint, node: Node): void { + function pipelineEmitWithHintWorker(hint: EmitHint, node: Node, allowSnippets = true): void { + if (allowSnippets) { + const snippet = getSnippetElement(node); + if (snippet) { + return emitSnippetNode(hint, node, snippet); + } + } if (hint === EmitHint.SourceFile) return emitSourceFile(cast(node, isSourceFile)); if (hint === EmitHint.IdentifierName) return emitIdentifier(cast(node, isIdentifier)); if (hint === EmitHint.JsxAttributeValue) return emitLiteral(cast(node, isStringLiteral), /*jsxAttributeEscape*/ true); @@ -1937,6 +1943,30 @@ namespace ts { } } + // + // Snippet Elements + // + + function emitSnippetNode(hint: EmitHint, node: Node, snippet: SnippetElement) { + switch (snippet.kind) { + case SnippetKind.Placeholder: + return emitPlaceholder(hint, node, snippet); + case SnippetKind.TabStop: + return emitTabStop(snippet); + } + } + + function emitPlaceholder(hint: EmitHint, node: Node, snippet: Placeholder) { + // write(`\$\{${order}:${defaultText}\}`); + write(`\$\{${snippet.order}:`); + pipelineEmitWithHintWorker(hint, node, /*allowSnippets*/ false); + write(`\}`); + } + + function emitTabStop(snippet: TabStop) { + write(`\$${snippet.order}`); + } + // // Identifiers // diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts index 8f032fd8b764e..fa4489ee7da7e 100644 --- a/src/compiler/factory/emitNode.ts +++ b/src/compiler/factory/emitNode.ts @@ -256,6 +256,22 @@ namespace ts { } } + /** + * Gets the SnippetElement of a node. + */ + export function getSnippetElement(node: Node): SnippetElement | undefined { + return node.emitNode?.snippetElement; + } + + /** + * Sets the SnippetElement of a node. + */ + export function setSnippetElement(node: T, snippet: SnippetElement): T { + const emitNode = getOrCreateEmitNode(node); + emitNode.snippetElement = snippet; + return node; + } + /* @internal */ export function ignoreSourceNewlines(node: T): T { getOrCreateEmitNode(node).flags |= EmitFlags.IgnoreSourceNewlines; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0888e8807292f..55e452fb30c78 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6740,16 +6740,14 @@ namespace ts { snippetElement?: SnippetElement; // Snippet element of the node } - export interface SnippetElement { - kind: SnippetKind; - } + export type SnippetElement = TabStop | Placeholder; - export interface TabStop extends SnippetElement { + export interface TabStop { kind: SnippetKind.TabStop; order: number; } - export interface PlaceHolder extends SnippetElement { + export interface Placeholder { kind: SnippetKind.Placeholder; order: number; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 19784af87c0ff..a96753dcf0812 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3142,7 +3142,7 @@ namespace ts { return undefined; } - export function isKeyword(token: SyntaxKind): boolean { + export function isKeyword(token: SyntaxKind): token is KeywordSyntaxKind { return SyntaxKind.FirstKeyword <= token && token <= SyntaxKind.LastKeyword; } @@ -3327,7 +3327,7 @@ namespace ts { return node.escapedText === "push" || node.escapedText === "unshift"; } - export function isParameterDeclaration(node: VariableLikeDeclaration) { + export function isParameterDeclaration(node: VariableLikeDeclaration): node is ParameterDeclaration { const root = getRootDeclaration(node); return root.kind === SyntaxKind.Parameter; } diff --git a/src/services/completions.ts b/src/services/completions.ts index c1ba3f4045aca..3f0447347d2a8 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -760,8 +760,11 @@ namespace ts.Completions { let body; if (preferences.includeCompletionsWithSnippetText) { isSnippet = true; - const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier("$1")); - body = factory.createBlock([tabStopStatement], /* multiline */ true); + // const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier("$1")); + // body = factory.createBlock([tabStopStatement], /* multiline */ true); + const emptyStatement = factory.createExpressionStatement(factory.createIdentifier("")); + setSnippetElement(emptyStatement, { kind: SnippetKind.TabStop, order: 0 }); + body = factory.createBlock([emptyStatement], /* multiline */ true); } else { body = factory.createBlock([], /* multiline */ true); @@ -813,6 +816,7 @@ namespace ts.Completions { concatenate([factory.createModifier(SyntaxKind.OverrideKeyword)], node.modifiers), ); } + addSnippets(node); completionNodes.push(node); }, body); @@ -823,6 +827,32 @@ namespace ts.Completions { return { insertText, isSnippet }; } + + function addSnippets(node: Node): void { + let order = 1; + addSnippetsWorker(node); + + function addSnippetsWorker(node: Node) { + if (isVariableLike(node) && isParameterDeclaration(node)) { + // Placeholder + setSnippetElement(node.name, { kind: SnippetKind.Placeholder, order }); + order += 1; + if (node.type) { + setSnippetElement(node.type, { kind: SnippetKind.Placeholder, order }); + order += 1; + } + } + else if (isFunctionLikeDeclaration(node)) { + if (node.type) { + setSnippetElement(node.type, { kind: SnippetKind.Placeholder, order }); + order += 1; + } + } + + forEachChild(node, addSnippetsWorker); + } + } + function originToCompletionEntryData(origin: SymbolOriginInfoExport): CompletionEntryData | undefined { return { exportName: origin.exportName, diff --git a/src/services/snippets.ts b/src/services/snippets.ts new file mode 100644 index 0000000000000..b1590d57c276a --- /dev/null +++ b/src/services/snippets.ts @@ -0,0 +1,23 @@ +/* @internal */ +namespace ts.snippets { + // interface SnippetWriter extends EmitTextWriter, PrintHandlers {} + + // function createSnippetWriter(newLine: string): SnippetWriter { + // const substituteNode = (hint: EmitHint, node: Node) => { + // switch (hint) { + // case EmitHint.IdentifierName: + // // >> TODO: do escaping here + // return node; + // } + // return node; + // }; + + // const writer = createTextWriter(newLine); + + + // return { + // ...writer, + // substituteNode, + // }; + // } +} diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 1e0934804edda..729386a3b77f6 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -33,6 +33,7 @@ "preProcess.ts", "rename.ts", "smartSelection.ts", + "snippets.ts", "signatureHelp.ts", "inlayHints.ts", "sourcemaps.ts", From b124c8448a108859c725c6869b317a62299c9511 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 5 Oct 2021 12:21:35 -0700 Subject: [PATCH 11/38] make add snippets work with overloads (not synced) --- src/compiler/emitter.ts | 8 ++++---- src/services/completions.ts | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5c9aaf23c1180..e873e0919577a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1957,10 +1957,10 @@ namespace ts { } function emitPlaceholder(hint: EmitHint, node: Node, snippet: Placeholder) { - // write(`\$\{${order}:${defaultText}\}`); - write(`\$\{${snippet.order}:`); - pipelineEmitWithHintWorker(hint, node, /*allowSnippets*/ false); - write(`\}`); + write(`\$\{${snippet.order}:`); // `${2:` + pipelineEmitWithHintWorker(hint, node, /*allowSnippets*/ false); // `...` + write(`\}`); // `}` + // `${2:...}` } function emitTabStop(snippet: TabStop) { diff --git a/src/services/completions.ts b/src/services/completions.ts index 3f0447347d2a8..5625993b18fa2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -816,23 +816,25 @@ namespace ts.Completions { concatenate([factory.createModifier(SyntaxKind.OverrideKeyword)], node.modifiers), ); } - addSnippets(node); completionNodes.push(node); }, body); if (completionNodes.length) { + addSnippets(completionNodes); insertText = printer.printList(ListFormat.MultiLine, factory.createNodeArray(completionNodes), sourceFile); } return { insertText, isSnippet }; } - function addSnippets(node: Node): void { + function addSnippets(nodes: Node[]): void { let order = 1; - addSnippetsWorker(node); + for (const node of nodes) { + addSnippetsWorker(node, undefined); + } - function addSnippetsWorker(node: Node) { + function addSnippetsWorker(node: Node, parent: Node | undefined) { if (isVariableLike(node) && isParameterDeclaration(node)) { // Placeholder setSnippetElement(node.name, { kind: SnippetKind.Placeholder, order }); @@ -842,14 +844,12 @@ namespace ts.Completions { order += 1; } } - else if (isFunctionLikeDeclaration(node)) { - if (node.type) { - setSnippetElement(node.type, { kind: SnippetKind.Placeholder, order }); - order += 1; - } + else if (isTypeNode(node) && parent && isFunctionLikeDeclaration(parent)) { + setSnippetElement(node, { kind: SnippetKind.Placeholder, order }); + order += 1; } - forEachChild(node, addSnippetsWorker); + forEachChild(node, child => addSnippetsWorker(child, node)); } } From db408cc9c2f40c1d5608c2591bd23a534ee74cb6 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 5 Oct 2021 16:37:55 -0700 Subject: [PATCH 12/38] fix snippet adding --- src/services/completions.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 5625993b18fa2..81442b66d41ef 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -760,8 +760,8 @@ namespace ts.Completions { let body; if (preferences.includeCompletionsWithSnippetText) { isSnippet = true; - // const tabStopStatement = factory.createExpressionStatement(factory.createIdentifier("$1")); - // body = factory.createBlock([tabStopStatement], /* multiline */ true); + // We are adding a final tabstop (i.e. $0) in the body of the suggested member, if it has one. + // NOTE: this assumes we won't have more than one body in the completion nodes. const emptyStatement = factory.createExpressionStatement(factory.createIdentifier("")); setSnippetElement(emptyStatement, { kind: SnippetKind.TabStop, order: 0 }); body = factory.createBlock([emptyStatement], /* multiline */ true); @@ -821,7 +821,9 @@ namespace ts.Completions { body); if (completionNodes.length) { - addSnippets(completionNodes); + if (preferences.includeCompletionsWithSnippetText) { + addSnippets(completionNodes); + } insertText = printer.printList(ListFormat.MultiLine, factory.createNodeArray(completionNodes), sourceFile); } return { insertText, isSnippet }; From d7809c11226ec4d5b832067b1312689631e002b5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 6 Oct 2021 13:38:25 -0700 Subject: [PATCH 13/38] rebase --- .github/pr_owners.txt | 3 +- .../workflows/accept-baselines-fix-lints.yaml | 1 + .github/workflows/ci.yml | 2 +- lib/lib.es2021.d.ts | 1 + package-lock.json | 325 +- package.json | 2 +- src/compiler/binder.ts | 4 +- src/compiler/builder.ts | 18 +- src/compiler/builderState.ts | 5 +- src/compiler/checker.ts | 1784 ++-- src/compiler/commandLineParser.ts | 156 +- src/compiler/diagnosticMessages.json | 145 +- src/compiler/emitter.ts | 76 +- src/compiler/factory/emitHelpers.ts | 32 +- src/compiler/factory/nodeFactory.ts | 85 +- src/compiler/factory/nodeTests.ts | 8 + src/compiler/factory/parenthesizerRules.ts | 2 +- src/compiler/factory/utilities.ts | 13 +- src/compiler/moduleNameResolver.ts | 630 +- src/compiler/moduleSpecifiers.ts | 141 +- src/compiler/parser.ts | 179 +- src/compiler/program.ts | 203 +- src/compiler/resolutionCache.ts | 62 +- src/compiler/scanner.ts | 1 + src/compiler/sourcemap.ts | 3 +- src/compiler/transformer.ts | 4 + src/compiler/transformers/classFields.ts | 36 +- src/compiler/transformers/declarations.ts | 16 +- src/compiler/transformers/jsx.ts | 9 +- .../transformers/module/esnextAnd2015.ts | 125 +- src/compiler/transformers/module/module.ts | 12 +- src/compiler/transformers/module/node.ts | 84 + src/compiler/transformers/ts.ts | 71 +- src/compiler/tsbuildPublic.ts | 17 +- src/compiler/tsconfig.json | 1 + src/compiler/types.ts | 129 +- src/compiler/utilities.ts | 218 +- src/compiler/utilitiesPublic.ts | 11 +- src/compiler/visitorPublic.ts | 20 +- src/compiler/watch.ts | 2 +- src/compiler/watchPublic.ts | 4 +- src/compiler/watchUtilities.ts | 2 +- src/deprecatedCompat/deprecations.ts | 2 +- src/executeCommandLine/executeCommandLine.ts | 26 +- src/harness/compilerImpl.ts | 14 +- src/harness/fourslashImpl.ts | 26 +- src/harness/fourslashInterfaceImpl.ts | 17 +- src/harness/harnessIO.ts | 8 +- src/harness/vpathUtil.ts | 2 +- src/lib/README.md | 24 +- src/lib/dom.generated.d.ts | 2565 ++---- src/lib/dom.iterable.generated.d.ts | 64 +- src/lib/es2015.iterable.d.ts | 12 +- src/lib/es2015.promise.d.ts | 76 +- src/lib/es2018.intl.d.ts | 34 +- src/lib/es2020.intl.d.ts | 287 +- src/lib/es2020.promise.d.ts | 5 +- src/lib/es2021.d.ts | 1 + src/lib/es2021.intl.d.ts | 24 + src/lib/es2021.promise.d.ts | 9 +- src/lib/es5.d.ts | 108 +- src/lib/esnext.intl.d.ts | 11 +- src/lib/libs.json | 1 + src/lib/webworker.generated.d.ts | 703 +- src/lib/webworker.iterable.generated.d.ts | 40 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- .../diagnosticMessages.generated.json.lcl | 321 +- src/server/editorServices.ts | 2 +- src/server/project.ts | 8 +- src/server/protocol.ts | 1 + src/server/session.ts | 10 +- src/server/watchType.ts | 2 - .../codefixes/convertFunctionToEs6Class.ts | 2 +- src/services/codefixes/convertToEs6Module.ts | 12 +- .../codefixes/convertToTypeOnlyExport.ts | 8 +- .../codefixes/convertToTypeOnlyImport.ts | 3 +- .../fixForgottenThisPropertyAccess.ts | 4 +- .../codefixes/fixModuleAndTargetOptions.ts | 4 +- src/services/codefixes/fixSpelling.ts | 16 +- src/services/codefixes/helpers.ts | 2 +- src/services/codefixes/importFixes.ts | 459 +- src/services/codefixes/requireInTs.ts | 4 +- src/services/codefixes/splitTypeOnlyImport.ts | 6 +- src/services/completions.ts | 293 +- src/services/documentRegistry.ts | 2 +- src/services/findAllReferences.ts | 26 +- src/services/formatting/formatting.ts | 33 +- src/services/getEditsForFileRename.ts | 5 +- src/services/goToDefinition.ts | 6 +- src/services/inlayHints.ts | 2 +- src/services/organizeImports.ts | 14 +- src/services/refactors/convertExport.ts | 4 +- src/services/refactors/convertImport.ts | 6 +- src/services/refactors/moveToNewFile.ts | 7 +- src/services/rename.ts | 2 +- src/services/services.ts | 27 +- src/services/stringCompletions.ts | 29 +- src/services/suggestionDiagnostics.ts | 2 +- src/services/transpile.ts | 2 +- src/services/types.ts | 10 +- src/services/utilities.ts | 9 +- src/testRunner/compilerRunner.ts | 5 +- src/testRunner/parallel/host.ts | 2 +- src/testRunner/parallel/worker.ts | 2 +- .../unittests/config/commandLineParsing.ts | 2 +- .../config/convertCompilerOptionsFromJson.ts | 33 +- src/testRunner/unittests/moduleResolution.ts | 22 +- src/testRunner/unittests/programApi.ts | 2 +- .../unittests/reuseProgramStructure.ts | 19 +- .../unittests/services/organizeImports.ts | 7 + .../unittests/services/textChanges.ts | 20 +- src/testRunner/unittests/transform.ts | 7 +- .../unittests/tsbuild/moduleResolution.ts | 90 + .../unittests/tsbuild/moduleSpecifiers.ts | 97 + .../unittests/tsbuildWatch/programUpdates.ts | 8 +- .../unittests/tscWatch/incremental.ts | 3 + .../unittests/tsserver/getExportReferences.ts | 16 +- .../unittests/tsserver/projectReferences.ts | 6 +- src/testRunner/unittests/tsserver/rename.ts | 11 +- .../unittests/tsserver/symlinkCache.ts | 5 + .../unittests/tsserver/typingsInstaller.ts | 2 +- .../reference/ArrowFunction1.symbols | 1 + ...leMemberThatUsesClassTypeParameter.symbols | 4 + ...duleMemberThatUsesClassTypeParameter.types | 8 +- .../FunctionDeclaration13_es6.symbols | 1 + .../reference/FunctionDeclaration13_es6.types | 2 +- ...sesCorrectly.Initial star ignores tag.json | 9 - ...rectly.Initial star space ignores tag.json | 9 - .../reference/ParameterList5.symbols | 1 + .../baselines/reference/ParameterList5.types | 2 +- tests/baselines/reference/TupleType6.symbols | 1 + ...WithExportedLocalVarsOfTheSameName.symbols | 3 + ...chWithExportedLocalVarsOfTheSameName.types | 6 +- ...sorDeclarationEmitVisibilityErrors.symbols | 1 + ...essorDeclarationEmitVisibilityErrors.types | 4 +- tests/baselines/reference/aliasBug.symbols | 1 + tests/baselines/reference/aliasBug.types | 2 +- tests/baselines/reference/aliasErrors.symbols | 1 + tests/baselines/reference/aliasErrors.types | 2 +- ...allowImportClausesToMergeWithTypes.symbols | 1 + .../allowImportClausesToMergeWithTypes.types | 2 +- ...hRelativeExternalImportDeclaration.symbols | 2 +- ...ithRelativeExternalImportDeclaration.types | 2 +- .../reference/api/tsserverlibrary.d.ts | 642 +- tests/baselines/reference/api/typescript.d.ts | 637 +- ...onFunctionsCanNarrowByDiscriminant.symbols | 2 + .../reference/assertionTypePredicates2.js | 50 + .../assertionTypePredicates2.symbols | 42 + .../reference/assertionTypePredicates2.types | 51 + ...assignmentCompatWithStringIndexer3.symbols | 1 + .../assignmentCompatWithStringIndexer3.types | 8 +- .../asyncArrowFunction10_es2017.symbols | 1 + .../asyncArrowFunction10_es2017.types | 2 +- .../asyncArrowFunction10_es5.symbols | 1 + .../reference/asyncArrowFunction10_es5.types | 2 +- .../asyncArrowFunction10_es6.symbols | 1 + .../reference/asyncArrowFunction10_es6.types | 2 +- .../asyncArrowFunction9_es2017.errors.txt | 2 +- .../asyncArrowFunction9_es5.errors.txt | 2 +- .../asyncArrowFunction9_es6.errors.txt | 2 +- .../asyncAwaitIsolatedModules_es2017.types | 34 +- .../asyncAwaitIsolatedModules_es5.types | 34 +- .../asyncAwaitIsolatedModules_es6.types | 34 +- .../asyncFunctionDeclaration13_es2017.symbols | 1 + .../asyncFunctionDeclaration13_es2017.types | 2 +- .../asyncFunctionDeclaration13_es5.symbols | 1 + .../asyncFunctionDeclaration13_es5.types | 2 +- .../asyncFunctionDeclaration13_es6.symbols | 1 + .../asyncFunctionDeclaration13_es6.types | 2 +- .../reference/augmentExportEquals1.symbols | 2 + .../reference/augmentExportEquals1.types | 2 +- .../reference/augmentExportEquals1_1.symbols | 2 + .../reference/augmentExportEquals1_1.types | 2 +- .../reference/augmentExportEquals2.symbols | 2 + .../reference/augmentExportEquals2.types | 2 +- .../reference/augmentExportEquals2_1.symbols | 2 + .../reference/augmentExportEquals2_1.types | 2 +- .../awaitInNonAsyncFunction.errors.txt | 8 +- .../reference/awaitedType.errors.txt | 168 + tests/baselines/reference/awaitedType.js | 262 + tests/baselines/reference/awaitedType.symbols | 396 + tests/baselines/reference/awaitedType.types | 352 + .../awaitedTypeStrictNull.errors.txt | 68 + .../reference/awaitedTypeStrictNull.js | 85 + .../reference/awaitedTypeStrictNull.symbols | 220 + .../reference/awaitedTypeStrictNull.types | 170 + .../badExternalModuleReference.symbols | 4 +- .../badExternalModuleReference.types | 4 +- .../baseExpressionTypeParameters.symbols | 1 + .../baseExpressionTypeParameters.types | 6 +- .../baselines/reference/bigintWithLib.symbols | 8 +- .../reference/bigintWithoutLib.symbols | 2 + .../reference/bigintWithoutLib.types | 42 +- .../reference/bluebirdStaticThis.symbols | 5 + .../reference/bluebirdStaticThis.types | 10 +- .../reference/boolInsteadOfBoolean.symbols | 1 + .../reference/boolInsteadOfBoolean.types | 6 +- .../bundledNodeDTSFailsWithOutFlag.js | 81 - .../bundledNodeDTSFailsWithOutFlag.symbols | 34 - .../bundledNodeDTSFailsWithOutFlag.types | 36 - .../reference/bundledNodeDTSPassesWithFlag.js | 81 - .../bundledNodeDTSPassesWithFlag.symbols | 34 - .../bundledNodeDTSPassesWithFlag.types | 36 - .../reference/bundledNodeDTSWithExports.js | 72 - .../bundledNodeDTSWithExports.symbols | 31 - .../reference/bundledNodeDTSWithExports.types | 33 - .../bundledNodeDTSWithScopedPackage.js | 81 - .../bundledNodeDTSWithScopedPackage.symbols | 34 - .../bundledNodeDTSWithScopedPackage.types | 36 - ...ExpressionWithMissingTypeArgument1.symbols | 5 +- .../reference/callWithSpread4.symbols | 1 + tests/baselines/reference/callbackTag2.types | 4 +- .../checkJsdocTypedefOnlySourceFile.types | 2 +- ...nalNoInfiniteInstantiationDepth.errors.txt | 196 + .../classTypeParametersInStatics.symbols | 3 + .../classTypeParametersInStatics.types | 26 +- ...commonJsExportTypeDeclarationError.symbols | 4 + .../reference/commonMissingSemicolons.symbols | 93 - .../reference/commonMissingSemicolons.types | 164 - ...sonOperatorWithIntersectionType.errors.txt | 15 + .../comparisonOperatorWithIntersectionType.js | 11 + ...arisonOperatorWithIntersectionType.symbols | 16 + ...mparisonOperatorWithIntersectionType.types | 20 + .../completionImportCallAssertion.baseline | 140 + .../completionsCommentsClass.baseline | 12 + .../completionsCommentsClassMembers.baseline | 24 + ...completionsCommentsCommentParsing.baseline | 24 + ...letionsCommentsFunctionExpression.baseline | 24 + .../computedPropertyNames32_ES5.symbols | 1 + .../computedPropertyNames32_ES6.symbols | 1 + .../computedPropertyNames34_ES5.symbols | 1 + .../computedPropertyNames34_ES6.symbols | 1 + .../computedPropertyNames35_ES5.symbols | 1 + .../computedPropertyNames35_ES6.symbols | 1 + ...mputedTypesKeyofNoIndexSignatureType.types | 2 +- ...eBigArrayConstraintsPerformance.errors.txt | 20 + ...eVarianceBigArrayConstraintsPerformance.js | 17 + ...anceBigArrayConstraintsPerformance.symbols | 34 + ...rianceBigArrayConstraintsPerformance.types | 24 + .../reference/conflictMarkerTrivia4.symbols | 1 + .../reference/conflictMarkerTrivia4.types | 4 +- .../reference/constAssertionOnEnum.js | 29 +- .../reference/constAssertionOnEnum.symbols | 30 + .../reference/constAssertionOnEnum.types | 29 + .../reference/constAssertions.symbols | 53 + ...nstEnumNamespaceReferenceCausesNoImport.js | 35 - ...umNamespaceReferenceCausesNoImport.symbols | 40 - ...EnumNamespaceReferenceCausesNoImport.types | 39 - .../constEnumPreserveEmitNamedExport1.js | 23 + .../constEnumPreserveEmitNamedExport1.symbols | 18 + .../constEnumPreserveEmitNamedExport1.types | 18 + .../constEnumPreserveEmitNamedExport2.js | 23 + .../constEnumPreserveEmitNamedExport2.symbols | 19 + .../constEnumPreserveEmitNamedExport2.types | 19 + .../reference/constantEnumAssert.symbols | 10 + .../reference/constraintErrors1.symbols | 1 + .../reference/constraintErrors1.types | 2 +- ...ructorWithIncompleteTypeAnnotation.symbols | 5 +- ...structorWithIncompleteTypeAnnotation.types | 16 +- .../reference/controlFlowAliasing.errors.txt | 19 +- .../reference/controlFlowAliasing.js | 20 + .../reference/controlFlowAliasing.symbols | 19 + .../reference/controlFlowAliasing.types | 23 + ...ables(useunknownincatchvariables=false).js | 51 + ...(useunknownincatchvariables=false).symbols | 56 + ...es(useunknownincatchvariables=false).types | 76 + ...seunknownincatchvariables=true).errors.txt | 33 + ...iables(useunknownincatchvariables=true).js | 51 + ...s(useunknownincatchvariables=true).symbols | 56 + ...les(useunknownincatchvariables=true).types | 76 + .../controlFlowAssignmentPatternOrder.symbols | 18 + .../controlFlowBindingPatternOrder.symbols | 6 + .../controlFlowTypeofObject.errors.txt | 77 + .../reference/controlFlowTypeofObject.js | 144 + .../reference/controlFlowTypeofObject.symbols | 136 + .../reference/controlFlowTypeofObject.types | 179 + .../correctOrderOfPromiseMethod.symbols | 8 +- .../correctOrderOfPromiseMethod.types | 8 +- .../declarationEmitIndexTypeNotFound.symbols | 1 + .../declarationEmitIndexTypeNotFound.types | 2 +- ...tionEmitInvalidReferenceAllowJs.errors.txt | 4 +- ...bdaWithMissingTypeParameterNoCrash.symbols | 2 + ...ambdaWithMissingTypeParameterNoCrash.types | 4 +- ...EmitMappedPrivateTypeTypeParameter.symbols | 1 + ...ypeParameterExtendingUnknownSymbol.symbols | 1 + .../declarationEmitUnknownImport.errors.txt | 5 +- .../declarationEmitUnknownImport2.errors.txt | 5 +- ...rMetadataNoLibIsolatedModulesTypes.symbols | 1 + ...torMetadataNoLibIsolatedModulesTypes.types | 2 +- ...ithImportDeclarationNameCollision4.symbols | 4 +- ...aWithImportDeclarationNameCollision4.types | 16 +- ...ithImportDeclarationNameCollision7.symbols | 4 + ...aWithImportDeclarationNameCollision7.types | 16 +- .../reference/deepComparisons.errors.txt | 49 + tests/baselines/reference/deepComparisons.js | 33 + .../reference/deepComparisons.symbols | 86 + .../baselines/reference/deepComparisons.types | 58 + .../defaultExportsCannotMerge01.symbols | 2 +- .../defaultExportsCannotMerge01.types | 4 +- .../defaultExportsCannotMerge02.symbols | 2 +- .../defaultExportsCannotMerge02.types | 4 +- .../defaultExportsCannotMerge03.symbols | 2 +- .../defaultExportsCannotMerge03.types | 4 +- ...sSuperCallsInNonConstructorMembers.symbols | 2 + ...assSuperCallsInNonConstructorMembers.types | 4 +- ...tructuringParameterDeclaration4.errors.txt | 2 +- .../reference/destructuringTuple.errors.txt | 4 +- .../didYouMeanStringLiteral.errors.txt | 20 + .../reference/didYouMeanStringLiteral.js | 14 + .../reference/didYouMeanStringLiteral.symbols | 24 + .../reference/didYouMeanStringLiteral.types | 22 + .../didYouMeanSuggestionErrors.symbols | 2 + .../didYouMeanSuggestionErrors.types | 4 +- .../reference/directReferenceToNull.symbols | 1 + .../reference/directReferenceToNull.types | 2 +- .../directReferenceToUndefined.symbols | 1 + .../directReferenceToUndefined.types | 2 +- ...teAssignabilityToTypeParameters.errors.txt | 8 +- ...aborateAssignabilityToTypeParameters.types | 6 +- ...eedToChangeYourTargetLibraryES2015.symbols | 6 + ...uNeedToChangeYourTargetLibraryES2015.types | 12 +- ...angeYourTargetLibraryES2016Plus.errors.txt | 36 +- ...NeedToChangeYourTargetLibraryES2016Plus.js | 4 +- ...oChangeYourTargetLibraryES2016Plus.symbols | 43 +- ...dToChangeYourTargetLibraryES2016Plus.types | 29 +- .../duplicateNumericIndexers.errors.txt | 2 +- .../duplicatePackageServices.baseline.jsonc | 707 ++ .../reference/emitCodeBeforeSuperCall.js | 53 - .../reference/emitCodeBeforeSuperCall.symbols | 51 - .../reference/emitCodeBeforeSuperCall.types | 60 - .../reference/emitCodeBeforeSuperCall2.js | 49 - .../emitCodeBeforeSuperCall2.symbols | 23 - .../reference/emitCodeBeforeSuperCall2.types | 24 - ...emitCodeBeforeSuperCallWithDefineFields.js | 74 - ...odeBeforeSuperCallWithDefineFields.symbols | 51 - ...tCodeBeforeSuperCallWithDefineFields.types | 60 - ...lpersWithLocalCollisions(module=es2022).js | 24 + ...lpersWithLocalCollisions(module=node12).js | 27 + ...ersWithLocalCollisions(module=nodenext).js | 27 + ...rrorForUsingPropertyOfTypeAsType01.symbols | 20 + .../errorForUsingPropertyOfTypeAsType01.types | 20 +- ...rrorForUsingPropertyOfTypeAsType02.symbols | 2 + .../errorForUsingPropertyOfTypeAsType02.types | 2 +- ...rrorForUsingPropertyOfTypeAsType03.symbols | 12 + .../errorForUsingPropertyOfTypeAsType03.types | 10 +- .../errorTypesAsTypeArguments.symbols | 2 + .../reference/errorTypesAsTypeArguments.types | 2 +- ...sForCallAndAssignmentAreSimilar.errors.txt | 8 +- .../errorsInGenericTypeReference.symbols | 21 + .../errorsInGenericTypeReference.types | 66 +- tests/baselines/reference/es2018IntlAPIs.js | 13 + .../reference/es2018IntlAPIs.symbols | 25 + .../baselines/reference/es2018IntlAPIs.types | 35 + tests/baselines/reference/es2020IntlAPIs.js | 75 + .../reference/es2020IntlAPIs.symbols | 149 + .../baselines/reference/es2020IntlAPIs.types | 209 + .../excessivelyLargeTupleSpread.symbols | 15 + ...MetadataUnresolvedTypeObjectInEmit.symbols | 1 + ...orMetadataUnresolvedTypeObjectInEmit.types | 4 +- .../exportAsNamespace1_amd.errors.txt | 22 - .../reference/exportAsNamespace1_amd.js | 48 - .../reference/exportAsNamespace1_amd.symbols | 32 - .../reference/exportAsNamespace1_amd.types | 41 - .../exportAsNamespace1_esnext.errors.txt | 22 - .../reference/exportAsNamespace1_esnext.js | 37 - .../exportAsNamespace1_esnext.symbols | 32 - .../reference/exportAsNamespace1_esnext.types | 41 - .../exportAsNamespace1_system.errors.txt | 22 - .../reference/exportAsNamespace1_system.js | 72 - .../exportAsNamespace1_system.symbols | 32 - .../reference/exportAsNamespace1_system.types | 41 - .../exportAsNamespace1_umd.errors.txt | 22 - .../reference/exportAsNamespace1_umd.js | 73 - .../reference/exportAsNamespace1_umd.symbols | 32 - .../reference/exportAsNamespace1_umd.types | 41 - .../exportAsNamespace2_amd.errors.txt | 22 - .../reference/exportAsNamespace2_amd.js | 56 - .../reference/exportAsNamespace2_amd.symbols | 32 - .../reference/exportAsNamespace2_amd.types | 41 - .../exportAsNamespace2_esnext.errors.txt | 22 - .../exportAsNamespace2_esnext.symbols | 32 - .../reference/exportAsNamespace2_esnext.types | 41 - .../exportAsNamespace2_system.errors.txt | 22 - .../reference/exportAsNamespace2_system.js | 72 - .../exportAsNamespace2_system.symbols | 32 - .../reference/exportAsNamespace2_system.types | 41 - .../exportAsNamespace2_umd.errors.txt | 22 - .../reference/exportAsNamespace2_umd.js | 87 - .../reference/exportAsNamespace2_umd.symbols | 32 - .../reference/exportAsNamespace2_umd.types | 41 - ...SpecifierAndLocalMemberDeclaration.symbols | 2 + ...rtSpecifierAndLocalMemberDeclaration.types | 2 +- ...cifierReferencingOuterDeclaration3.symbols | 1 + ...pecifierReferencingOuterDeclaration3.types | 2 +- ...cifierReferencingOuterDeclaration4.symbols | 1 + ...pecifierReferencingOuterDeclaration4.types | 2 +- .../reference/exportSpecifiers.errors.txt | 40 + tests/baselines/reference/exportSpecifiers.js | 48 + .../reference/exportSpecifiers.symbols | 54 + .../reference/exportSpecifiers.types | 57 + .../reference/extendArray.errors.txt | 10 +- tests/baselines/reference/extendArray.symbols | 2 + tests/baselines/reference/extendArray.types | 6 +- .../reference/externModule.errors.txt | 8 +- ...nMissingTypeArgsOnJSConstructCalls.symbols | 2 + ...lInMissingTypeArgsOnJSConstructCalls.types | 12 +- ...AllReferencesDynamicImport3.baseline.jsonc | 244 + ...ReferencesJSDocFunctionThis.baseline.jsonc | 36 + ...dAllReferencesOfConstructor.baseline.jsonc | 884 ++ ...encesUmdModuleAsGlobalConst.baseline.jsonc | 425 + .../findAllRefsBadImport.baseline.jsonc | 53 + ...findAllRefsClassExpression0.baseline.jsonc | 791 ++ ...findAllRefsClassExpression1.baseline.jsonc | 560 ++ ...findAllRefsClassExpression2.baseline.jsonc | 572 ++ ...fsClassWithStaticThisAccess.baseline.jsonc | 229 + .../findAllRefsCommonJsRequire.baseline.jsonc | 4 +- ...findAllRefsCommonJsRequire2.baseline.jsonc | 2 +- ...findAllRefsCommonJsRequire3.baseline.jsonc | 4 +- .../findAllRefsDefaultImport.baseline.jsonc | 345 + ...faultImportThroughNamespace.baseline.jsonc | 433 + .../findAllRefsDefinition.baseline.jsonc | 147 + ...ndAllRefsDestructureGeneric.baseline.jsonc | 262 + ...indAllRefsDestructureGetter.baseline.jsonc | 661 ++ ...ndAllRefsDestructureGetter2.baseline.jsonc | 481 + ...indAllRefsExportAsNamespace.baseline.jsonc | 557 ++ ...RefsExportConstEqualToClass.baseline.jsonc | 347 + .../findAllRefsExportEquals.baseline.jsonc | 1089 +++ ...llRefsForComputedProperties.baseline.jsonc | 614 ++ ...lRefsForComputedProperties2.baseline.jsonc | 578 ++ ...findAllRefsForDefaultExport.baseline.jsonc | 296 + ...ndAllRefsForDefaultExport04.baseline.jsonc | 985 ++ ...fsForDefaultExportAnonymous.baseline.jsonc | 233 + ...sForDefaultExport_anonymous.baseline.jsonc | 116 + ...fsForDefaultExport_reExport.baseline.jsonc | 1055 +++ ...llowSyntheticDefaultImports.baseline.jsonc | 1055 +++ .../findAllRefsForMappedType.baseline.jsonc | 109 + .../findAllRefsForModule.baseline.jsonc | 227 + .../findAllRefsForModuleGlobal.baseline.jsonc | 71 + .../findAllRefsForObjectSpread.baseline.jsonc | 488 + ...icInstanceMethodInheritance.baseline.jsonc | 667 ++ ...InstancePropertyInheritance.baseline.jsonc | 1440 +++ ...llRefsForStringLiteralTypes.baseline.jsonc | 95 + ...ariableInImplementsClause01.baseline.jsonc | 1 + ...fsGlobalThisKeywordInModule.baseline.jsonc | 1 + .../findAllRefsImportDefault.baseline.jsonc | 416 + .../findAllRefsImportEquals.baseline.jsonc | 81 + ...AllRefsImportEqualsJsonFile.baseline.jsonc | 461 + .../findAllRefsImportNamed.baseline.jsonc | 276 + ...efsImportStarOfExportEquals.baseline.jsonc | 2855 ++++++ ...indAllRefsInClassExpression.baseline.jsonc | 345 + ...AllRefsInheritedProperties3.baseline.jsonc | 1799 ++++ ...AllRefsInheritedProperties4.baseline.jsonc | 614 ++ ...AllRefsInheritedProperties5.baseline.jsonc | 383 + .../findAllRefsIsDefinition.baseline.jsonc | 945 ++ .../findAllRefsJsDocTypeDef.baseline.jsonc | 1 + ...indingElementPropertyName03.baseline.jsonc | 268 + ...indingElementPropertyName04.baseline.jsonc | 500 + ...indingElementPropertyName05.baseline.jsonc | 1 + ...indingElementPropertyName06.baseline.jsonc | 774 ++ ...indingElementPropertyName07.baseline.jsonc | 86 + .../findAllRefsOfConstructor.baseline.jsonc | 244 + .../findAllRefsOfConstructor2.baseline.jsonc | 287 + ...OfConstructor_multipleFiles.baseline.jsonc | 577 ++ ...sOfConstructor_withModifier.baseline.jsonc | 63 + .../findAllRefsOnImportAliases.baseline.jsonc | 677 ++ ...findAllRefsOnImportAliases2.baseline.jsonc | 1021 +++ ...rameterPropertyDeclaration1.baseline.jsonc | 155 + ...rameterPropertyDeclaration2.baseline.jsonc | 467 + ...rameterPropertyDeclaration3.baseline.jsonc | 467 + ...ertyDeclaration_inheritance.baseline.jsonc | 769 ++ ...lRefsPrefixSuffixPreference.baseline.jsonc | 1069 +++ ...textuallyTypedByTypeParam01.baseline.jsonc | 129 + .../findAllRefsReExportLocal.baseline.jsonc | 2522 +++++ ...eExportRightNameWrongSymbol.baseline.jsonc | 1259 +++ .../findAllRefsReExportStar.baseline.jsonc | 345 + .../findAllRefsReExportStarAs.baseline.jsonc | 526 ++ .../findAllRefsReExports.baseline.jsonc | 8165 +++++++++++++++++ .../findAllRefsReExports2.baseline.jsonc | 185 + ...efsReExportsUseInImportType.baseline.jsonc | 1228 +++ ...dPropertyInDerivedInterface.baseline.jsonc | 811 ++ ...efsRenameImportWithSameName.baseline.jsonc | 571 ++ .../findAllRefsRootSymbols.baseline.jsonc | 807 ++ .../findAllRefsUnionProperty.baseline.jsonc | 1901 ++++ ...ndAllRefsUnresolvedSymbols1.baseline.jsonc | 739 ++ ...ndAllRefsUnresolvedSymbols2.baseline.jsonc | 1103 +++ ...ndAllRefsUnresolvedSymbols3.baseline.jsonc | 1103 +++ ...ShorthandPropertyAssignment.baseline.jsonc | 468 + ...horthandPropertyAssignment2.baseline.jsonc | 384 + .../findAllRefsWriteAccess.baseline.jsonc | 161 + ...efs_importType_exportEquals.baseline.jsonc | 820 ++ .../findReferencesJSXTagName.baseline.jsonc | 493 + .../reference/forAwaitForUnion.types | 2 +- .../reference/formatToPartsBigInt.symbols | 20 +- .../functionTypesLackingReturnTypes.symbols | 2 + .../functionTypesLackingReturnTypes.types | 2 +- ...CallWithGenericSignatureArguments2.symbols | 2 + ...icCallWithGenericSignatureArguments2.types | 12 +- .../genericCapturingFunctionNarrowing.js | 28 + .../genericCapturingFunctionNarrowing.symbols | 53 + .../genericCapturingFunctionNarrowing.types | 44 + ...ClassWithStaticsUsingTypeArguments.symbols | 7 + ...icClassWithStaticsUsingTypeArguments.types | 34 +- ...wnNotAssignableToConcreteObject.errors.txt | 54 + ...dToUnknownNotAssignableToConcreteObject.js | 40 + ...knownNotAssignableToConcreteObject.symbols | 77 + ...UnknownNotAssignableToConcreteObject.types | 52 + .../reference/genericDefaultsErrors.symbols | 1 + .../reference/genericDefaultsErrors.types | 2 +- .../reference/genericFunduleInModule.symbols | 1 + .../reference/genericFunduleInModule.types | 2 +- .../reference/genericFunduleInModule2.symbols | 1 + .../reference/genericFunduleInModule2.types | 2 +- ...ergedDeclarationUsingTypeParameter.symbols | 2 + ...cMergedDeclarationUsingTypeParameter.types | 6 +- ...rgedDeclarationUsingTypeParameter2.symbols | 2 + ...MergedDeclarationUsingTypeParameter2.types | 6 +- ...cTypeReferenceWithoutTypeArgument2.symbols | 1 + ...ricTypeReferenceWithoutTypeArgument2.types | 4 +- ...sDefinitionOfBindingPattern.baseline.jsonc | 299 + ...rrencesIsDefinitionOfExport.baseline.jsonc | 333 + .../reference/hoverOverComment.baseline.jsonc | 1 + ...portAssertion1(module=commonjs).errors.txt | 78 + .../importAssertion1(module=commonjs).js | 92 + .../importAssertion1(module=commonjs).symbols | 104 + .../importAssertion1(module=commonjs).types | 137 + ...importAssertion1(module=es2015).errors.txt | 78 + .../importAssertion1(module=es2015).js | 85 + .../importAssertion1(module=es2015).symbols | 104 + .../importAssertion1(module=es2015).types | 137 + ...importAssertion1(module=esnext).errors.txt | 42 + .../importAssertion1(module=esnext).js | 85 + .../importAssertion1(module=esnext).symbols | 104 + .../importAssertion1(module=esnext).types | 137 + ...portAssertion2(module=commonjs).errors.txt | 34 + .../importAssertion2(module=commonjs).js | 65 + .../importAssertion2(module=commonjs).symbols | 28 + .../importAssertion2(module=commonjs).types | 39 + ...importAssertion2(module=es2015).errors.txt | 34 + .../importAssertion2(module=es2015).js | 41 + .../importAssertion2(module=es2015).symbols | 28 + .../importAssertion2(module=es2015).types | 39 + .../importAssertion2(module=esnext).js | 40 + .../importAssertion2(module=esnext).symbols | 28 + .../importAssertion2(module=esnext).types | 39 + ...importAssertion3(module=es2015).errors.txt | 26 + .../importAssertion3(module=es2015).js | 31 + .../importAssertion3(module=es2015).symbols | 17 + .../importAssertion3(module=es2015).types | 21 + ...importAssertion3(module=esnext).errors.txt | 26 + .../importAssertion3(module=esnext).js | 31 + .../importAssertion3(module=esnext).symbols | 17 + .../importAssertion3(module=esnext).types | 21 + ...portCallExpressionErrorInES2015.errors.txt | 12 +- ...mportCallExpressionGrammarError.errors.txt | 25 +- ...mportCallExpressionNestedES2015.errors.txt | 8 +- ...portCallExpressionNestedES20152.errors.txt | 8 +- .../importClause_namespaceImport.symbols | 1 + .../importClause_namespaceImport.types | 2 +- .../importDeclWithClassModifiers.types | 2 +- .../importDeclWithDeclareModifier.types | 2 +- .../importDeclWithExportModifier.types | 2 +- tests/baselines/reference/importHelpersES6.js | 5 +- .../reference/importHelpersES6.symbols | 19 +- .../reference/importHelpersES6.types | 12 + ...elpersNoHelpersForPrivateFields.errors.txt | 23 + .../importHelpersNoHelpersForPrivateFields.js | 32 + ...rtHelpersNoHelpersForPrivateFields.symbols | 26 + ...portHelpersNoHelpersForPrivateFields.types | 29 + ...eta(module=commonjs,target=es5).errors.txt | 52 +- ...portMeta(module=commonjs,target=es5).types | 8 +- ...(module=commonjs,target=esnext).errors.txt | 52 +- ...tMeta(module=commonjs,target=esnext).types | 8 +- ...importMeta(module=es2020,target=es5).types | 8 +- ...ortMeta(module=es2020,target=esnext).types | 8 +- ...importMeta(module=esnext,target=es5).types | 8 +- ...ortMeta(module=esnext,target=esnext).types | 8 +- ...importMeta(module=system,target=es5).types | 8 +- ...ortMeta(module=system,target=esnext).types | 8 +- .../reference/importSpecifiers1.errors.txt | 108 + .../baselines/reference/importSpecifiers1.js | 97 + .../reference/importSpecifiers1.symbols | 93 + .../reference/importSpecifiers1.types | 104 + .../importedModuleAddToGlobal.errors.txt | 5 +- .../importedModuleAddToGlobal.symbols | 2 + .../reference/importedModuleAddToGlobal.types | 2 +- .../inOperatorWithInvalidOperands.errors.txt | 32 +- .../reference/indexSignatures1.errors.txt | 9 + tests/baselines/reference/indexSignatures1.js | 18 + .../reference/indexSignatures1.symbols | 36 + .../reference/indexSignatures1.types | 19 + .../indirectJsRequireRename.baseline.jsonc | 2 +- ...ferFromGenericFunctionReturnTypes3.symbols | 4 +- ...inferFromGenericFunctionReturnTypes3.types | 10 +- tests/baselines/reference/inferTypes1.symbols | 2 + .../reference/inferenceLimit.symbols | 4 +- .../baselines/reference/inferenceLimit.types | 4 +- .../reference/infiniteConstraints.errors.txt | 5 +- .../inlineJsxAndJsxFragPragma.errors.txt | 87 + .../reference/inlineJsxAndJsxFragPragma.js | 104 +- .../inlineJsxAndJsxFragPragma.symbols | 71 + .../reference/inlineJsxAndJsxFragPragma.types | 87 +- .../inlineJsxFactoryDeclarationsLocalTypes.js | 36 +- .../baselines/reference/innerAliases.symbols | 2 + tests/baselines/reference/innerAliases.types | 4 +- .../instantiateTypeParameter.symbols | 1 + .../reference/instantiateTypeParameter.types | 2 +- ...ocalModuleWithoutExportAccessError.symbols | 1 + ...eLocalModuleWithoutExportAccessError.types | 2 +- ...ocalModuleWithoutExportAccessError.symbols | 2 + ...eLocalModuleWithoutExportAccessError.types | 2 +- .../intersectionsOfLargeUnions2.errors.txt | 2 +- .../reference/intrinsicKeyword.symbols | 6 + .../reference/intrinsicKeyword.types | 10 +- tests/baselines/reference/intrinsics.symbols | 1 + tests/baselines/reference/intrinsics.types | 2 +- .../invalidInstantiatedModule.errors.txt | 5 +- .../invalidInstantiatedModule.symbols | 2 + .../reference/invalidInstantiatedModule.types | 2 +- .../invalidSymbolInTypeParameter1.symbols | 1 + .../invalidSymbolInTypeParameter1.types | 4 +- ...idTaggedTemplateEscapeSequences.errors.txt | 49 - .../invalidTaggedTemplateEscapeSequences.js | 58 - ...validTaggedTemplateEscapeSequences.symbols | 85 - ...invalidTaggedTemplateEscapeSequences.types | 143 - .../invalidUseOfTypeAsNamespace.symbols | 2 + .../invalidUseOfTypeAsNamespace.types | 2 +- .../isolatedModulesReExportType.errors.txt | 17 +- .../reference/isolatedModulesReExportType.js | 14 + .../isolatedModulesReExportType.symbols | 20 + .../isolatedModulesReExportType.types | 22 +- .../jsDeclarationsJSDocRedirectedLookups.js | 53 +- tests/baselines/reference/jsDocTags.baseline | 732 -- .../jsFileCompilationTypeAliasSyntax.symbols | 1 + .../jsFileCompilationTypeAliasSyntax.types | 2 +- ...sFileCompilationWithMapFileAsJs.errors.txt | 4 +- ...hMapFileAsJsWithInlineSourceMap.errors.txt | 4 +- ...lationWithMapFileAsJsWithOutDir.errors.txt | 4 +- .../reference/jsdocInTypeScript.symbols | 1 + .../reference/jsdocInTypeScript.types | 2 +- .../reference/jsdocOuterTypeParameters1.types | 10 +- .../reference/jsdocOverrideTag1.errors.txt | 12 +- .../jsdocParameterParsingInfiniteLoop.types | 2 +- .../jsdocPropertyTagInvalid.errors.txt | 4 +- .../jsdocResolveNameFailureInTypedef.types | 4 +- .../jsdocTemplateTagDefault.errors.txt | 90 + .../reference/jsdocTemplateTagDefault.js | 186 + .../reference/jsdocTemplateTagDefault.symbols | 83 + .../reference/jsdocTemplateTagDefault.types | 91 + .../jsdocTemplateTagNameResolution.errors.txt | 16 + .../jsdocTemplateTagNameResolution.js | 30 + .../jsdocTemplateTagNameResolution.symbols | 15 + .../jsdocTemplateTagNameResolution.types | 18 + .../reference/jsdocTypeCast.errors.txt | 26 + tests/baselines/reference/jsdocTypeCast.js | 34 + .../baselines/reference/jsdocTypeCast.symbols | 33 + tests/baselines/reference/jsdocTypeCast.types | 38 + .../jsxFactoryAndFragment.errors.txt | 16 - .../reference/jsxFactoryAndFragment.js | 13 - .../reference/jsxFactoryAndFragment.symbols | 6 - .../reference/jsxFactoryAndFragment.types | 20 - ...ryIdentifierWithAbsentParameter.errors.txt | 5 +- ...oryQualifiedNameResolutionError.errors.txt | 5 +- ...ntrinsicElementsTypeArgumentErrors.symbols | 6 + .../reference/jsxUnclosedParserRecovery.js | 22 +- .../jsxUnclosedParserRecovery.symbols | 4 + .../reference/jsxUnclosedParserRecovery.types | 22 +- .../reference/keyRemappingKeyofResult.js | 99 + .../reference/keyRemappingKeyofResult.symbols | 193 + .../reference/keyRemappingKeyofResult.types | 173 + .../reference/keyofAndIndexedAccess2.symbols | 1 + .../keyofAndIndexedAccessErrors.symbols | 1 + .../reference/lambdaArgCrash.errors.txt | 4 +- .../reference/lambdaArgCrash.symbols | 1 + .../baselines/reference/lambdaArgCrash.types | 8 +- tests/baselines/reference/libCompileChecks.js | 7 + .../reference/libCompileChecks.symbols | 4 + .../reference/libCompileChecks.types | 4 + .../libTypeScriptOverrideSimple.errors.txt | 14 + .../reference/libTypeScriptOverrideSimple.js | 18 + .../libTypeScriptOverrideSimple.symbols | 15 + .../libTypeScriptOverrideSimple.types | 19 + .../libTypeScriptSubfileResolving.errors.txt | 16 + .../libTypeScriptSubfileResolving.js | 20 + .../libTypeScriptSubfileResolving.symbols | 17 + .../libTypeScriptSubfileResolving.types | 21 + .../literalTypesAndDestructuring.symbols | 2 + .../localGetReferences.baseline.jsonc | 5 + tests/baselines/reference/localTypes4.symbols | 2 + tests/baselines/reference/localTypes4.types | 4 +- .../mapConstructorOnReadonlyTuple.symbols | 1 + ...mappedTypeAsClauseRelationships.errors.txt | 40 + .../mappedTypeAsClauseRelationships.js | 41 + .../mappedTypeAsClauseRelationships.symbols | 142 + .../mappedTypeAsClauseRelationships.types | 64 + .../reference/mappedTypeAsClauses.types | 12 +- .../reference/mappedTypeNoTypeNoCrash.symbols | 2 + .../mappedTypeRecursiveInference.errors.txt | 8 +- .../mappedTypeRecursiveInference.types | 12 +- ...ithAsClauseAndLateBoundProperty.errors.txt | 2 +- .../reference/mappedTypesArraysTuples.js | 8 +- .../reference/mappedTypesArraysTuples.symbols | 32 +- .../reference/mappedTypesArraysTuples.types | 6 +- .../reference/moduleAssignmentCompat1.symbols | 2 + .../reference/moduleAssignmentCompat1.types | 16 +- .../reference/moduleAssignmentCompat2.symbols | 2 + .../reference/moduleAssignmentCompat2.types | 16 +- .../reference/moduleAssignmentCompat3.symbols | 2 + .../reference/moduleAssignmentCompat3.types | 16 +- .../reference/moduleAssignmentCompat4.symbols | 2 + .../reference/moduleAssignmentCompat4.types | 16 +- ...moduleAugmentationImportsAndExports2.types | 2 +- ...moduleAugmentationImportsAndExports3.types | 12 +- .../moduleClassArrayCodeGenTest.symbols | 1 + .../moduleClassArrayCodeGenTest.types | 2 +- .../reference/moduleCrashBug1.symbols | 1 + .../baselines/reference/moduleCrashBug1.types | 2 +- .../reference/moduleInTypePosition1.symbols | 1 + .../reference/moduleInTypePosition1.types | 6 +- .../reference/moduleNewExportBug.symbols | 1 + .../reference/moduleNewExportBug.types | 2 +- .../moduleNodeNextImportFix.baseline | 24 + .../reference/moduleResolutionNoTs.errors.txt | 31 - .../reference/moduleResolutionNoTs.js | 34 - .../reference/moduleResolutionNoTs.symbols | 33 - .../reference/moduleResolutionNoTs.types | 33 - .../reference/moduleVisibilityTest2.symbols | 2 + .../reference/moduleVisibilityTest2.types | 4 +- .../reference/moduleVisibilityTest3.symbols | 3 + .../reference/moduleVisibilityTest3.types | 6 +- .../reference/moduleVisibilityTest4.symbols | 4 + .../reference/moduleVisibilityTest4.types | 8 +- .../moduleWithNoValuesAsType.symbols | 3 + .../reference/moduleWithNoValuesAsType.types | 6 +- .../reference/moduleWithValuesAsType.symbols | 1 + .../reference/moduleWithValuesAsType.types | 2 +- ...pertyAccessAndArrowFunctionIndent1.symbols | 4 + ...ropertyAccessAndArrowFunctionIndent1.types | 12 +- ...pleClassPropertyModifiersErrors.errors.txt | 18 +- ...ltipleClassPropertyModifiersErrors.symbols | 3 +- ...multipleClassPropertyModifiersErrors.types | 1 + ...espaceMergedWithImportAliasNoCrash.symbols | 1 + ...amespaceMergedWithImportAliasNoCrash.types | 2 +- .../reference/namespacesDeclaration2.symbols | 3 + .../reference/namespacesDeclaration2.types | 6 +- .../reference/narrowByEquality.errors.txt | 19 +- tests/baselines/reference/narrowByEquality.js | 28 + .../reference/narrowByEquality.symbols | 51 +- .../reference/narrowByEquality.types | 31 + ...wExceptionVariableInCatchClause.errors.txt | 2 +- .../narrowFromAnyWithInstanceof.errors.txt | 4 +- .../narrowFromAnyWithTypePredicate.errors.txt | 4 +- .../reference/noAsConstNameLookup.symbols | 3 + .../noCrashOnImportShadowing.symbols | 1 + .../reference/noCrashOnImportShadowing.types | 2 +- ...sPackageSelfName(module=node12).errors.txt | 24 + ...deAllowJsPackageSelfName(module=node12).js | 63 + ...owJsPackageSelfName(module=node12).symbols | 24 + ...llowJsPackageSelfName(module=node12).types | 24 + ...ackageSelfName(module=nodenext).errors.txt | 24 + ...AllowJsPackageSelfName(module=nodenext).js | 63 + ...JsPackageSelfName(module=nodenext).symbols | 24 + ...owJsPackageSelfName(module=nodenext).types | 24 + .../nodeModules1(module=node12).errors.txt | 564 ++ .../reference/nodeModules1(module=node12).js | 696 ++ .../nodeModules1(module=node12).symbols | 817 ++ .../nodeModules1(module=node12).types | 997 ++ .../nodeModules1(module=nodenext).errors.txt | 564 ++ .../nodeModules1(module=nodenext).js | 696 ++ .../nodeModules1(module=nodenext).symbols | 817 ++ .../nodeModules1(module=nodenext).types | 997 ++ ...eModulesAllowJs1(module=node12).errors.txt | 597 ++ .../nodeModulesAllowJs1(module=node12).js | 692 ++ ...nodeModulesAllowJs1(module=node12).symbols | 817 ++ .../nodeModulesAllowJs1(module=node12).types | 997 ++ ...odulesAllowJs1(module=nodenext).errors.txt | 597 ++ .../nodeModulesAllowJs1(module=nodenext).js | 692 ++ ...deModulesAllowJs1(module=nodenext).symbols | 817 ++ ...nodeModulesAllowJs1(module=nodenext).types | 997 ++ ...alPackageExports(module=node12).errors.txt | 135 + ...onditionalPackageExports(module=node12).js | 201 + ...ionalPackageExports(module=node12).symbols | 243 + ...itionalPackageExports(module=node12).types | 246 + ...PackageExports(module=nodenext).errors.txt | 135 + ...ditionalPackageExports(module=nodenext).js | 201 + ...nalPackageExports(module=nodenext).symbols | 243 + ...ionalPackageExports(module=nodenext).types | 246 + ...ulesAllowJsDynamicImport(module=node12).js | 45 + ...llowJsDynamicImport(module=node12).symbols | 22 + ...sAllowJsDynamicImport(module=node12).types | 26 + ...esAllowJsDynamicImport(module=nodenext).js | 45 + ...owJsDynamicImport(module=nodenext).symbols | 22 + ...llowJsDynamicImport(module=nodenext).types | 26 + ...ExportAssignment(module=node12).errors.txt | 41 + ...sAllowJsExportAssignment(module=node12).js | 61 + ...wJsExportAssignment(module=node12).symbols | 36 + ...lowJsExportAssignment(module=node12).types | 45 + ...portAssignment(module=nodenext).errors.txt | 41 + ...llowJsExportAssignment(module=nodenext).js | 61 + ...sExportAssignment(module=nodenext).symbols | 36 + ...wJsExportAssignment(module=nodenext).types | 45 + ...edNameCollisions(module=node12).errors.txt | 38 + ...sGeneratedNameCollisions(module=node12).js | 62 + ...ratedNameCollisions(module=node12).symbols | 38 + ...neratedNameCollisions(module=node12).types | 42 + ...NameCollisions(module=nodenext).errors.txt | 38 + ...eneratedNameCollisions(module=nodenext).js | 62 + ...tedNameCollisions(module=nodenext).symbols | 38 + ...ratedNameCollisions(module=nodenext).types | 42 + ...ImportAssignment(module=node12).errors.txt | 49 + ...sAllowJsImportAssignment(module=node12).js | 68 + ...wJsImportAssignment(module=node12).symbols | 43 + ...lowJsImportAssignment(module=node12).types | 51 + ...portAssignment(module=nodenext).errors.txt | 49 + ...llowJsImportAssignment(module=nodenext).js | 68 + ...sImportAssignment(module=nodenext).symbols | 43 + ...wJsImportAssignment(module=nodenext).types | 51 + ...lpersCollisions1(module=node12).errors.txt | 36 + ...ImportHelpersCollisions1(module=node12).js | 52 + ...tHelpersCollisions1(module=node12).symbols | 40 + ...ortHelpersCollisions1(module=node12).types | 48 + ...ersCollisions1(module=nodenext).errors.txt | 36 + ...portHelpersCollisions1(module=nodenext).js | 52 + ...elpersCollisions1(module=nodenext).symbols | 40 + ...tHelpersCollisions1(module=nodenext).types | 48 + ...lpersCollisions2(module=node12).errors.txt | 32 + ...ImportHelpersCollisions2(module=node12).js | 48 + ...tHelpersCollisions2(module=node12).symbols | 22 + ...ortHelpersCollisions2(module=node12).types | 22 + ...ersCollisions2(module=nodenext).errors.txt | 32 + ...portHelpersCollisions2(module=nodenext).js | 48 + ...elpersCollisions2(module=nodenext).symbols | 22 + ...tHelpersCollisions2(module=nodenext).types | 22 + ...lpersCollisions3(module=node12).errors.txt | 31 + ...ImportHelpersCollisions3(module=node12).js | 54 + ...tHelpersCollisions3(module=node12).symbols | 36 + ...ortHelpersCollisions3(module=node12).types | 36 + ...ersCollisions3(module=nodenext).errors.txt | 31 + ...portHelpersCollisions3(module=nodenext).js | 54 + ...elpersCollisions3(module=nodenext).symbols | 36 + ...tHelpersCollisions3(module=nodenext).types | 36 + ...llowJsImportMeta(module=node12).errors.txt | 23 + ...ModulesAllowJsImportMeta(module=node12).js | 38 + ...esAllowJsImportMeta(module=node12).symbols | 22 + ...ulesAllowJsImportMeta(module=node12).types | 24 + ...owJsImportMeta(module=nodenext).errors.txt | 23 + ...dulesAllowJsImportMeta(module=nodenext).js | 38 + ...AllowJsImportMeta(module=nodenext).symbols | 22 + ...esAllowJsImportMeta(module=nodenext).types | 24 + ...JsPackageExports(module=node12).errors.txt | 107 + ...lesAllowJsPackageExports(module=node12).js | 161 + ...lowJsPackageExports(module=node12).symbols | 174 + ...AllowJsPackageExports(module=node12).types | 174 + ...PackageExports(module=nodenext).errors.txt | 107 + ...sAllowJsPackageExports(module=nodenext).js | 161 + ...wJsPackageExports(module=nodenext).symbols | 174 + ...lowJsPackageExports(module=nodenext).types | 174 + ...JsPackageImports(module=node12).errors.txt | 44 + ...lesAllowJsPackageImports(module=node12).js | 92 + ...lowJsPackageImports(module=node12).symbols | 60 + ...AllowJsPackageImports(module=node12).types | 60 + ...PackageImports(module=nodenext).errors.txt | 44 + ...sAllowJsPackageImports(module=nodenext).js | 92 + ...wJsPackageImports(module=nodenext).symbols | 60 + ...lowJsPackageImports(module=nodenext).types | 60 + ...gePatternExports(module=node12).errors.txt | 78 + ...wJsPackagePatternExports(module=node12).js | 120 + ...ckagePatternExports(module=node12).symbols | 120 + ...PackagePatternExports(module=node12).types | 120 + ...PatternExports(module=nodenext).errors.txt | 78 + ...sPackagePatternExports(module=nodenext).js | 120 + ...agePatternExports(module=nodenext).symbols | 120 + ...ckagePatternExports(module=nodenext).types | 120 + ...nExportsTrailers(module=node12).errors.txt | 120 + ...gePatternExportsTrailers(module=node12).js | 120 + ...ternExportsTrailers(module=node12).symbols | 120 + ...atternExportsTrailers(module=node12).types | 120 + ...xportsTrailers(module=nodenext).errors.txt | 78 + ...PatternExportsTrailers(module=nodenext).js | 120 + ...rnExportsTrailers(module=nodenext).symbols | 120 + ...ternExportsTrailers(module=nodenext).types | 120 + ...ronousCallErrors(module=node12).errors.txt | 55 + ...wJsSynchronousCallErrors(module=node12).js | 60 + ...nchronousCallErrors(module=node12).symbols | 58 + ...SynchronousCallErrors(module=node12).types | 68 + ...nousCallErrors(module=nodenext).errors.txt | 55 + ...sSynchronousCallErrors(module=nodenext).js | 60 + ...hronousCallErrors(module=nodenext).symbols | 58 + ...nchronousCallErrors(module=nodenext).types | 68 + ...wJsTopLevelAwait(module=node12).errors.txt | 34 + ...ulesAllowJsTopLevelAwait(module=node12).js | 42 + ...llowJsTopLevelAwait(module=node12).symbols | 22 + ...sAllowJsTopLevelAwait(module=node12).types | 28 + ...sTopLevelAwait(module=nodenext).errors.txt | 28 + ...esAllowJsTopLevelAwait(module=nodenext).js | 42 + ...owJsTopLevelAwait(module=nodenext).symbols | 22 + ...llowJsTopLevelAwait(module=nodenext).types | 28 + ...rmatFileAlwaysHasDefault(module=node12).js | 36 + ...ileAlwaysHasDefault(module=node12).symbols | 13 + ...tFileAlwaysHasDefault(module=node12).types | 14 + ...atFileAlwaysHasDefault(module=nodenext).js | 36 + ...eAlwaysHasDefault(module=nodenext).symbols | 13 + ...ileAlwaysHasDefault(module=nodenext).types | 14 + ...alPackageExports(module=node12).errors.txt | 135 + ...onditionalPackageExports(module=node12).js | 201 + ...ionalPackageExports(module=node12).symbols | 243 + ...itionalPackageExports(module=node12).types | 246 + ...PackageExports(module=nodenext).errors.txt | 135 + ...ditionalPackageExports(module=nodenext).js | 201 + ...nalPackageExports(module=nodenext).symbols | 243 + ...ionalPackageExports(module=nodenext).types | 246 + ...tionEmitDynamicImportWithPackageExports.js | 280 + ...mitDynamicImportWithPackageExports.symbols | 108 + ...nEmitDynamicImportWithPackageExports.types | 141 + ...thPackageExports(module=node12).errors.txt | 116 + ...onEmitWithPackageExports(module=node12).js | 198 + ...tWithPackageExports(module=node12).symbols | 201 + ...mitWithPackageExports(module=node12).types | 204 + ...PackageExports(module=nodenext).errors.txt | 116 + ...EmitWithPackageExports(module=nodenext).js | 198 + ...ithPackageExports(module=nodenext).symbols | 201 + ...tWithPackageExports(module=nodenext).types | 204 + ...nodeModulesDynamicImport(module=node12).js | 45 + ...odulesDynamicImport(module=node12).symbols | 22 + ...eModulesDynamicImport(module=node12).types | 26 + ...deModulesDynamicImport(module=nodenext).js | 45 + ...ulesDynamicImport(module=nodenext).symbols | 22 + ...odulesDynamicImport(module=nodenext).types | 26 + ...xportAssignments(module=node12).errors.txt | 23 + ...ModulesExportAssignments(module=node12).js | 38 + ...esExportAssignments(module=node12).symbols | 16 + ...ulesExportAssignments(module=node12).types | 18 + ...ortAssignments(module=nodenext).errors.txt | 23 + ...dulesExportAssignments(module=nodenext).js | 38 + ...ExportAssignments(module=nodenext).symbols | 16 + ...esExportAssignments(module=nodenext).types | 18 + ...cifierResolution(module=node12).errors.txt | 36 + ...locksSpecifierResolution(module=node12).js | 30 + ...SpecifierResolution(module=node12).symbols | 25 + ...ksSpecifierResolution(module=node12).types | 26 + ...fierResolution(module=nodenext).errors.txt | 33 + ...cksSpecifierResolution(module=nodenext).js | 30 + ...ecifierResolution(module=nodenext).symbols | 25 + ...SpecifierResolution(module=nodenext).types | 26 + ...rationConditions(module=node12).errors.txt | 40 + ...fierGenerationConditions(module=node12).js | 41 + ...enerationConditions(module=node12).symbols | 25 + ...rGenerationConditions(module=node12).types | 26 + ...tionConditions(module=nodenext).errors.txt | 37 + ...erGenerationConditions(module=nodenext).js | 41 + ...erationConditions(module=nodenext).symbols | 25 + ...enerationConditions(module=nodenext).types | 26 + ...erationDirectory(module=node12).errors.txt | 35 + ...ifierGenerationDirectory(module=node12).js | 36 + ...GenerationDirectory(module=node12).symbols | 25 + ...erGenerationDirectory(module=node12).types | 26 + ...ationDirectory(module=nodenext).errors.txt | 32 + ...ierGenerationDirectory(module=nodenext).js | 36 + ...nerationDirectory(module=nodenext).symbols | 25 + ...GenerationDirectory(module=nodenext).types | 26 + ...enerationPattern(module=node12).errors.txt | 38 + ...ecifierGenerationPattern(module=node12).js | 36 + ...erGenerationPattern(module=node12).symbols | 22 + ...fierGenerationPattern(module=node12).types | 26 + ...erationPattern(module=nodenext).errors.txt | 32 + ...ifierGenerationPattern(module=nodenext).js | 36 + ...GenerationPattern(module=nodenext).symbols | 25 + ...erGenerationPattern(module=nodenext).types | 26 + ...esForbidenSyntax(module=node12).errors.txt | 139 + ...odeModulesForbidenSyntax(module=node12).js | 172 + ...dulesForbidenSyntax(module=node12).symbols | 120 + ...ModulesForbidenSyntax(module=node12).types | 168 + ...ForbidenSyntax(module=nodenext).errors.txt | 139 + ...eModulesForbidenSyntax(module=nodenext).js | 172 + ...lesForbidenSyntax(module=nodenext).symbols | 120 + ...dulesForbidenSyntax(module=nodenext).types | 168 + ...edNameCollisions(module=node12).errors.txt | 38 + ...sGeneratedNameCollisions(module=node12).js | 64 + ...ratedNameCollisions(module=node12).symbols | 38 + ...neratedNameCollisions(module=node12).types | 42 + ...NameCollisions(module=nodenext).errors.txt | 38 + ...eneratedNameCollisions(module=nodenext).js | 64 + ...tedNameCollisions(module=nodenext).symbols | 38 + ...ratedNameCollisions(module=nodenext).types | 42 + ...ModulesImportAssignments(module=node12).js | 65 + ...esImportAssignments(module=node12).symbols | 43 + ...ulesImportAssignments(module=node12).types | 51 + ...dulesImportAssignments(module=nodenext).js | 65 + ...ImportAssignments(module=nodenext).symbols | 43 + ...esImportAssignments(module=nodenext).types | 51 + ...elpersCollisions(module=node12).errors.txt | 36 + ...sImportHelpersCollisions(module=node12).js | 52 + ...rtHelpersCollisions(module=node12).symbols | 40 + ...portHelpersCollisions(module=node12).types | 48 + ...persCollisions(module=nodenext).errors.txt | 36 + ...mportHelpersCollisions(module=nodenext).js | 52 + ...HelpersCollisions(module=nodenext).symbols | 40 + ...rtHelpersCollisions(module=nodenext).types | 48 + ...lpersCollisions2(module=node12).errors.txt | 32 + ...ImportHelpersCollisions2(module=node12).js | 47 + ...tHelpersCollisions2(module=node12).symbols | 22 + ...ortHelpersCollisions2(module=node12).types | 22 + ...ersCollisions2(module=nodenext).errors.txt | 32 + ...portHelpersCollisions2(module=nodenext).js | 47 + ...elpersCollisions2(module=nodenext).symbols | 22 + ...tHelpersCollisions2(module=nodenext).types | 22 + ...lpersCollisions3(module=node12).errors.txt | 27 + ...ImportHelpersCollisions3(module=node12).js | 44 + ...tHelpersCollisions3(module=node12).symbols | 20 + ...ortHelpersCollisions3(module=node12).types | 20 + ...ersCollisions3(module=nodenext).errors.txt | 27 + ...portHelpersCollisions3(module=nodenext).js | 44 + ...elpersCollisions3(module=nodenext).symbols | 20 + ...tHelpersCollisions3(module=nodenext).types | 20 + ...odulesImportMeta(module=node12).errors.txt | 23 + .../nodeModulesImportMeta(module=node12).js | 40 + ...deModulesImportMeta(module=node12).symbols | 22 + ...nodeModulesImportMeta(module=node12).types | 24 + ...ulesImportMeta(module=nodenext).errors.txt | 23 + .../nodeModulesImportMeta(module=nodenext).js | 40 + ...ModulesImportMeta(module=nodenext).symbols | 22 + ...deModulesImportMeta(module=nodenext).types | 24 + ...portResolutionIntoExport(module=node12).js | 66 + ...esolutionIntoExport(module=node12).symbols | 24 + ...tResolutionIntoExport(module=node12).types | 24 + ...rtResolutionIntoExport(module=nodenext).js | 66 + ...olutionIntoExport(module=nodenext).symbols | 24 + ...esolutionIntoExport(module=nodenext).types | 24 + ...esolutionNoCycle(module=node12).errors.txt | 33 + ...sImportResolutionNoCycle(module=node12).js | 66 + ...rtResolutionNoCycle(module=node12).symbols | 24 + ...portResolutionNoCycle(module=node12).types | 24 + ...olutionNoCycle(module=nodenext).errors.txt | 33 + ...mportResolutionNoCycle(module=nodenext).js | 66 + ...ResolutionNoCycle(module=nodenext).symbols | 24 + ...rtResolutionNoCycle(module=nodenext).types | 24 + ...esPackageExports(module=node12).errors.txt | 107 + ...odeModulesPackageExports(module=node12).js | 161 + ...dulesPackageExports(module=node12).symbols | 174 + ...ModulesPackageExports(module=node12).types | 174 + ...PackageExports(module=nodenext).errors.txt | 107 + ...eModulesPackageExports(module=nodenext).js | 161 + ...lesPackageExports(module=nodenext).symbols | 174 + ...dulesPackageExports(module=nodenext).types | 174 + ...esPackageImports(module=node12).errors.txt | 44 + ...odeModulesPackageImports(module=node12).js | 92 + ...dulesPackageImports(module=node12).symbols | 60 + ...ModulesPackageImports(module=node12).types | 60 + ...PackageImports(module=nodenext).errors.txt | 44 + ...eModulesPackageImports(module=nodenext).js | 92 + ...lesPackageImports(module=nodenext).symbols | 60 + ...dulesPackageImports(module=nodenext).types | 60 + ...gePatternExports(module=node12).errors.txt | 78 + ...lesPackagePatternExports(module=node12).js | 120 + ...ckagePatternExports(module=node12).symbols | 120 + ...PackagePatternExports(module=node12).types | 120 + ...PatternExports(module=nodenext).errors.txt | 78 + ...sPackagePatternExports(module=nodenext).js | 120 + ...agePatternExports(module=nodenext).symbols | 120 + ...ckagePatternExports(module=nodenext).types | 120 + ...nExportsTrailers(module=node12).errors.txt | 120 + ...gePatternExportsTrailers(module=node12).js | 120 + ...ternExportsTrailers(module=node12).symbols | 120 + ...atternExportsTrailers(module=node12).types | 120 + ...xportsTrailers(module=nodenext).errors.txt | 78 + ...PatternExportsTrailers(module=nodenext).js | 120 + ...rnExportsTrailers(module=nodenext).symbols | 120 + ...ternExportsTrailers(module=nodenext).types | 120 + ...ronousCallErrors(module=node12).errors.txt | 43 + ...lesSynchronousCallErrors(module=node12).js | 60 + ...nchronousCallErrors(module=node12).symbols | 58 + ...SynchronousCallErrors(module=node12).types | 68 + ...nousCallErrors(module=nodenext).errors.txt | 43 + ...sSynchronousCallErrors(module=nodenext).js | 60 + ...hronousCallErrors(module=nodenext).symbols | 58 + ...nchronousCallErrors(module=nodenext).types | 68 + ...lesTopLevelAwait(module=node12).errors.txt | 34 + ...nodeModulesTopLevelAwait(module=node12).js | 44 + ...odulesTopLevelAwait(module=node12).symbols | 22 + ...eModulesTopLevelAwait(module=node12).types | 28 + ...sTopLevelAwait(module=nodenext).errors.txt | 28 + ...deModulesTopLevelAwait(module=nodenext).js | 44 + ...ulesTopLevelAwait(module=nodenext).symbols | 22 + ...odulesTopLevelAwait(module=nodenext).types | 28 + ...pesVersionPackageExports(module=node12).js | 94 + ...rsionPackageExports(module=node12).symbols | 57 + ...VersionPackageExports(module=node12).types | 63 + ...sVersionPackageExports(module=nodenext).js | 94 + ...ionPackageExports(module=nodenext).symbols | 57 + ...rsionPackageExports(module=nodenext).types | 63 + ...ePackageSelfName(module=node12).errors.txt | 24 + .../nodePackageSelfName(module=node12).js | 63 + ...nodePackageSelfName(module=node12).symbols | 24 + .../nodePackageSelfName(module=node12).types | 24 + ...ackageSelfName(module=nodenext).errors.txt | 24 + .../nodePackageSelfName(module=nodenext).js | 63 + ...dePackageSelfName(module=nodenext).symbols | 24 + ...nodePackageSelfName(module=nodenext).types | 24 + ...geSelfNameScoped(module=node12).errors.txt | 24 + ...odePackageSelfNameScoped(module=node12).js | 63 + ...ckageSelfNameScoped(module=node12).symbols | 24 + ...PackageSelfNameScoped(module=node12).types | 24 + ...SelfNameScoped(module=nodenext).errors.txt | 24 + ...ePackageSelfNameScoped(module=nodenext).js | 63 + ...ageSelfNameScoped(module=nodenext).symbols | 24 + ...ckageSelfNameScoped(module=nodenext).types | 24 + ...PropertyAvailableOnPromisedType.errors.txt | 10 - ...existentPropertyAvailableOnPromisedType.js | 10 - ...entPropertyAvailableOnPromisedType.symbols | 10 - ...stentPropertyAvailableOnPromisedType.types | 12 - ...exerConstrainsPropertyDeclarations.symbols | 1 + ...ndexerConstrainsPropertyDeclarations.types | 6 +- .../objectLiteralExcessProperties.errors.txt | 8 +- .../objectLiteralExcessProperties.symbols | 1 + .../objectLiteralExcessProperties.types | 2 +- .../reference/organizeImports/Unused_Empty.ts | 7 - .../Unused_false_positive_export_shorthand.ts | 9 - ...sed_false_positive_shorthand_assignment.ts | 9 - tests/baselines/reference/override16.js | 17 - tests/baselines/reference/override16.symbols | 16 - tests/baselines/reference/override16.types | 17 - .../reference/override_js2.errors.txt | 16 +- .../reference/override_js4.errors.txt | 4 +- .../parseErrorIncorrectReturnToken.symbols | 1 + .../reference/parseInvalidNames.errors.txt | 97 + .../baselines/reference/parseInvalidNames.js | 37 + .../reference/parseInvalidNames.symbols | 12 + .../reference/parseInvalidNames.types | 33 + .../parser.forAwait.es2018.errors.txt | 8 +- .../reference/parser0_004152.symbols | 1 + .../baselines/reference/parser0_004152.types | 2 +- .../baselines/reference/parser553699.symbols | 1 + tests/baselines/reference/parser553699.types | 4 +- .../reference/parserAmbiguity1.symbols | 4 +- ...parserAmbiguityWithBinaryOperator4.symbols | 2 + .../parserCastVersusArrowFunction1.symbols | 4 + .../parserCastVersusArrowFunction1.types | 8 +- .../baselines/reference/parserClass2.symbols | 1 + tests/baselines/reference/parserClass2.types | 6 +- .../parserComputedPropertyName9.symbols | 1 + .../parserComputedPropertyName9.types | 2 +- .../parserConstructorAmbiguity3.symbols | 1 + .../parserES5ComputedPropertyName9.symbols | 1 + .../parserES5ComputedPropertyName9.types | 2 +- ...antEqualsGreaterThanAfterFunction2.symbols | 1 + ...rrantEqualsGreaterThanAfterFunction2.types | 4 +- ...Recovery_IncompleteMemberVariable2.symbols | 1 + ...orRecovery_IncompleteMemberVariable2.types | 2 +- ...parserErrorRecovery_ParameterList6.symbols | 1 + .../parserErrorRecovery_ParameterList6.types | 4 +- .../parserGenericConstraint2.symbols | 1 + .../parserGenericConstraint3.symbols | 1 + .../parserGenericConstraint4.symbols | 2 + .../parserGenericConstraint5.symbols | 2 + .../parserGenericConstraint6.symbols | 2 + .../parserGenericConstraint7.symbols | 2 + ...serGenericsInInterfaceDeclaration1.symbols | 1 + ...arserGenericsInInterfaceDeclaration1.types | 2 +- .../parserGenericsInTypeContexts1.symbols | 18 + .../parserGenericsInTypeContexts1.types | 14 +- .../parserGenericsInTypeContexts2.symbols | 54 + .../parserGenericsInTypeContexts2.types | 14 +- ...rserGenericsInVariableDeclaration1.symbols | 18 + ...parserGenericsInVariableDeclaration1.types | 12 +- .../parserIndexMemberDeclaration10.errors.txt | 4 +- .../parserIndexMemberDeclaration10.symbols | 1 + .../parserIndexMemberDeclaration10.types | 1 + .../parserMemberAccessExpression1.symbols | 17 +- ...arserMemberAccessorDeclaration8.errors.txt | 4 +- .../parserMemberAccessorDeclaration8.js | 2 +- .../parserMemberAccessorDeclaration8.symbols | 3 +- .../parserMemberAccessorDeclaration8.types | 1 + ...arserMemberFunctionDeclaration2.errors.txt | 4 +- .../parserMemberFunctionDeclaration2.js | 2 +- .../parserMemberFunctionDeclaration2.symbols | 3 +- .../parserMemberFunctionDeclaration2.types | 1 + ...arserMemberVariableDeclaration2.errors.txt | 4 +- .../parserMemberVariableDeclaration2.symbols | 3 +- .../parserMemberVariableDeclaration2.types | 1 + .../parserMissingLambdaOpenBrace1.symbols | 4 + .../parserMissingLambdaOpenBrace1.types | 6 +- .../reference/parserObjectType5.symbols | 1 + .../reference/parserObjectType5.types | 4 +- .../reference/parserObjectType6.symbols | 1 + .../reference/parserObjectType6.types | 4 +- .../reference/parserParameterList5.symbols | 1 + .../reference/parserParameterList5.types | 2 +- .../reference/parserRealSource10.symbols | 2 + .../reference/parserRealSource10.types | 226 +- .../reference/parserRealSource11.symbols | 170 + .../reference/parserRealSource11.types | 2176 ++--- .../reference/parserRealSource12.symbols | 100 + .../reference/parserRealSource12.types | 1970 ++-- .../reference/parserRealSource13.symbols | 113 + .../reference/parserRealSource13.types | 484 +- .../reference/parserRealSource14.symbols | 73 + .../reference/parserRealSource14.types | 1618 ++-- .../reference/parserRealSource5.symbols | 7 + .../reference/parserRealSource5.types | 28 +- .../reference/parserRealSource6.symbols | 44 + .../reference/parserRealSource6.types | 420 +- .../reference/parserRealSource7.symbols | 90 + .../reference/parserRealSource7.types | 1496 +-- .../reference/parserRealSource8.symbols | 46 + .../reference/parserRealSource8.types | 786 +- .../reference/parserRealSource9.symbols | 21 + .../reference/parserRealSource9.types | 438 +- .../reference/parserS7.2_A1.5_T2.errors.txt | 4 +- .../reference/parserS7.3_A1.1_T2.errors.txt | 2 +- .../reference/parserS7.6_A4.2_T1.errors.txt | 20 +- .../reference/parserSkippedTokens20.symbols | 2 + .../reference/parserSkippedTokens20.types | 2 +- .../reference/parserSuperExpression3.symbols | 1 + .../reference/parserTypeQuery8.symbols | 1 + .../reference/parserTypeQuery8.types | 2 +- ...nfinishedTypeNameBeforeKeyword1.errors.txt | 4 +- ...erUnfinishedTypeNameBeforeKeyword1.symbols | 2 + .../reference/parserUnicode1.errors.txt | 4 +- .../parserUnterminatedGeneric1.errors.txt | 8 +- .../parserUnterminatedGeneric1.symbols | 2 + .../parserUnterminatedGeneric1.types | 4 +- .../parserUnterminatedGeneric2.errors.txt | 8 +- .../parserUnterminatedGeneric2.symbols | 2 + .../parserUnterminatedGeneric2.types | 4 +- .../parserVariableDeclaration3.symbols | 2 + .../parserVariableDeclaration3.types | 4 +- .../reference/parserX_ArrowFunction1.symbols | 1 + .../baselines/reference/parserharness.symbols | 84 + tests/baselines/reference/parserharness.types | 692 +- .../reference/parserindenter.symbols | 59 + .../baselines/reference/parserindenter.types | 888 +- .../parservoidInQualifiedName2.symbols | 2 + .../parservoidInQualifiedName2.types | 2 +- ...gBasedModuleResolution1_classic.errors.txt | 22 - ...pingBasedModuleResolution1_classic.symbols | 4 - ...gBasedModuleResolution1_classic.trace.json | 1 - ...appingBasedModuleResolution1_classic.types | 5 - ...eImports(isolatedmodules=false).errors.txt | 36 + ...erveValueImports(isolatedmodules=false).js | 44 + ...alueImports(isolatedmodules=false).symbols | 46 + ...eValueImports(isolatedmodules=false).types | 50 + ...ueImports(isolatedmodules=true).errors.txt | 39 + ...serveValueImports(isolatedmodules=true).js | 44 + ...ValueImports(isolatedmodules=true).symbols | 46 + ...veValueImports(isolatedmodules=true).types | 50 + ...ueImports_errors(isolatedmodules=false).js | 73 + ...orts_errors(isolatedmodules=false).symbols | 95 + ...mports_errors(isolatedmodules=false).types | 95 + ...ts_errors(isolatedmodules=true).errors.txt | 74 + ...lueImports_errors(isolatedmodules=true).js | 73 + ...ports_errors(isolatedmodules=true).symbols | 95 + ...Imports_errors(isolatedmodules=true).types | 95 + ...erveValueImports_importsNotUsedAsValues.js | 20 + ...alueImports_importsNotUsedAsValues.symbols | 22 + ...eValueImports_importsNotUsedAsValues.types | 22 + ...eserveValueImports_mixedImports.errors.txt | 15 + .../preserveValueImports_mixedImports.js | 19 + .../preserveValueImports_mixedImports.symbols | 17 + .../preserveValueImports_mixedImports.types | 16 + ...ValueImports_module(module=amd).errors.txt | 7 + ...reserveValueImports_module(module=amd).js} | 8 +- ...Imports_module(module=commonjs).errors.txt | 7 + ...rveValueImports_module(module=commonjs).js | 7 + ...serveValueImports_module(module=es2015).js | 6 + ...ueImports_module(module=system).errors.txt | 7 + ...serveValueImports_module(module=system).js | 14 + .../primaryExpressionMods.errors.txt | 5 +- .../reference/primaryExpressionMods.symbols | 3 + .../reference/primaryExpressionMods.types | 6 +- .../privacyImportParseErrors.symbols | 20 +- .../reference/privacyImportParseErrors.types | 32 +- .../privateNameHashCharName.errors.txt | 5 +- .../reference/privateNameHashCharName.types | 1 - .../privateNameInInExpression.errors.txt | 146 + .../reference/privateNameInInExpression.js | 222 + .../privateNameInInExpression.symbols | 269 + .../reference/privateNameInInExpression.types | 308 + ...ressionTransform(target=es2020).errors.txt | 61 + ...eInInExpressionTransform(target=es2020).js | 97 + ...ExpressionTransform(target=es2020).symbols | 112 + ...InExpressionTransform(target=es2020).types | 141 + ...ressionTransform(target=esnext).errors.txt | 64 + ...eInInExpressionTransform(target=esnext).js | 87 + ...ExpressionTransform(target=esnext).symbols | 112 + ...InExpressionTransform(target=esnext).types | 141 + ...privateNameInInExpressionUnused.errors.txt | 16 + .../privateNameInInExpressionUnused.js | 22 + .../privateNameInInExpressionUnused.symbols | 23 + .../privateNameInInExpressionUnused.types | 22 + .../privateNameStaticFieldInitializer.js | 13 - .../privateNameStaticFieldInitializer.symbols | 11 - .../privateNameStaticFieldInitializer.types | 12 - ...ateNamesIncompatibleModifiersJs.errors.txt | 110 + .../privateNamesIncompatibleModifiersJs.js | 82 + ...rivateNamesIncompatibleModifiersJs.symbols | 80 + .../privateNamesIncompatibleModifiersJs.types | 89 + .../amd/invalidRootFile.errors.txt | 8 +- .../node/invalidRootFile.errors.txt | 8 +- ...entNamesNotSpecifiedWithAllowJs.errors.txt | 16 - ...ferentNamesSpecifiedWithAllowJs.errors.txt | 17 - ...SameNameDTsSpecifiedWithAllowJs.errors.txt | 12 - ...SameNameDTsSpecifiedWithAllowJs.errors.txt | 12 - ...ameFilesNotSpecifiedWithAllowJs.errors.txt | 9 - ...ameFilesNotSpecifiedWithAllowJs.errors.txt | 9 - ...meNameFilesSpecifiedWithAllowJs.errors.txt | 12 - ...meNameFilesSpecifiedWithAllowJs.errors.txt | 12 - .../reference/promisePermutations.errors.txt | 2 +- .../reference/promisePermutations2.errors.txt | 2 +- .../reference/promisePermutations3.errors.txt | 4 +- ...AssignmentMergeWithInterfaceMethod.symbols | 7 + ...tyAssignmentMergeWithInterfaceMethod.types | 16 +- .../quickInfoDisplayPartsVar.shims.baseline | 1112 --- ...TypeAtReturnPositionsInaccurate.errors.txt | 10 +- ...kinfoTypeAtReturnPositionsInaccurate.types | 4 +- .../raiseErrorOnParameterProperty.symbols | 1 + .../raiseErrorOnParameterProperty.types | 2 +- ...ferredInferenceAllowsAssignment.errors.txt | 279 + .../readonlyTupleAndArrayElaboration.symbols | 1 + .../recursiveClassReferenceTest.symbols | 1 + .../recursiveClassReferenceTest.types | 2 +- .../recursiveConditionalTypes.errors.txt | 30 +- .../reference/recursiveConditionalTypes.js | 22 +- .../recursiveConditionalTypes.symbols | 50 +- .../reference/recursiveConditionalTypes.types | 38 +- .../recursiveResolveTypeMembers.symbols | 2 + .../recursiveTypeComparison2.symbols | 1 + .../reference/recursiveTypeComparison2.types | 4 +- .../recursiveTypeRelations.errors.txt | 4 +- .../reference/recursiveTypeRelations.symbols | 2 + .../reference/recursiveTypeRelations.types | 10 +- .../reference/redefineArray.errors.txt | 2 +- .../redefinedPararameterProperty.symbols | 3 - .../redefinedPararameterProperty.types | 3 - ...arameterPropertyDeclaration.baseline.jsonc | 494 + .../reference/references01.baseline.jsonc | 66 + .../referencesBloomFilters.baseline.jsonc | 111 + .../referencesBloomFilters2.baseline.jsonc | 111 + .../referencesForClassMembers.baseline.jsonc | 1091 +++ ...mbersExtendingAbstractClass.baseline.jsonc | 1091 +++ ...embersExtendingGenericClass.baseline.jsonc | 1343 +++ ...ypedObjectLiteralProperties.baseline.jsonc | 206 + ...xtuallyTypedUnionProperties.baseline.jsonc | 3441 +++++++ ...tuallyTypedUnionProperties2.baseline.jsonc | 189 + ...encesForDeclarationKeywords.baseline.jsonc | 1256 +++ ...rencesForExpressionKeywords.baseline.jsonc | 1269 +++ ...erencesForIllegalAssignment.baseline.jsonc | 107 + ...encesForInheritedProperties.baseline.jsonc | 1119 +++ ...ncesForInheritedProperties2.baseline.jsonc | 282 + ...ncesForInheritedProperties5.baseline.jsonc | 363 + ...ncesForInheritedProperties6.baseline.jsonc | 186 + ...ncesForInheritedProperties7.baseline.jsonc | 1271 +++ ...ncesForInheritedProperties8.baseline.jsonc | 269 + .../referencesForLabel2.baseline.jsonc | 1 + ...encesForMergedDeclarations3.baseline.jsonc | 221 + ...encesForMergedDeclarations5.baseline.jsonc | 405 + ...encesForMergedDeclarations7.baseline.jsonc | 469 + .../referencesForModifiers.baseline.jsonc | 861 ++ .../referencesForNoContext.baseline.jsonc | 7 + ...NumericLiteralPropertyNames.baseline.jsonc | 125 + .../referencesForOverrides.baseline.jsonc | 1659 ++++ ...erencesForStatementKeywords.baseline.jsonc | 3160 +++++++ ...rStringLiteralPropertyNames.baseline.jsonc | 135 + ...StringLiteralPropertyNames4.baseline.jsonc | 183 + ...StringLiteralPropertyNames5.baseline.jsonc | 183 + ...StringLiteralPropertyNames6.baseline.jsonc | 173 + ...StringLiteralPropertyNames7.baseline.jsonc | 199 + .../referencesForTypeKeywords.baseline.jsonc | 511 ++ ...eferencesForUnionProperties.baseline.jsonc | 739 ++ .../referencesInComment.baseline.jsonc | 7 + ...ferencesInConfiguredProject.baseline.jsonc | 65 + .../renameDefaultImport.baseline.jsonc | 293 + ...eDefaultImportDifferentName.baseline.jsonc | 241 + ...eImportAndExportInDiffFiles.baseline.jsonc | 512 ++ .../renameImportOfExportEquals.baseline.jsonc | 861 ++ ...renameImportOfExportEquals2.baseline.jsonc | 937 ++ .../renameImportOfReExport.baseline.jsonc | 677 ++ .../renameImportOfReExport2.baseline.jsonc | 598 ++ .../renameJsExports01.baseline.jsonc | 120 + .../renameJsExports02.baseline.jsonc | 240 + .../renameJsExports03.baseline.jsonc | 479 + .../requireOfJsonFileWithAmd.errors.txt | 5 +- .../reference/requireOfJsonFileWithAmd.js | 5 + .../requireOfJsonFileWithAmd.symbols | 10 + .../reference/requireOfJsonFileWithAmd.types | 24 +- ...ireOfJsonFileWithModuleEmitNone.errors.txt | 5 +- .../requireOfJsonFileWithModuleEmitNone.js | 5 + ...equireOfJsonFileWithModuleEmitNone.symbols | 8 + .../requireOfJsonFileWithModuleEmitNone.types | 14 +- .../requireOfJsonFile_PathMapping.trace.json | 18 +- .../baselines/reference/scannerClass2.symbols | 1 + tests/baselines/reference/scannerClass2.types | 6 +- .../reference/scannerS7.2_A1.5_T2.errors.txt | 4 +- .../reference/scannerS7.3_A1.1_T2.errors.txt | 2 +- .../reference/scannerS7.6_A4.2_T1.errors.txt | 20 +- .../bundledPackageName/tsconfig.json | 5 - .../pedanticOverride/tsconfig.json | 5 - .../preserveValueImports/tsconfig.json | 5 + .../project/tsconfig.json | 3 - .../strictAwaitedTypes/tsconfig.json | 5 - .../strictGeneratorTypes/tsconfig.json | 5 - .../strictOptionalProperties/tsconfig.json | 5 - .../reference/sourceMapSample.symbols | 1 + .../baselines/reference/sourceMapSample.types | 2 +- .../reference/staticAsIdentifier.errors.txt | 23 +- .../baselines/reference/staticAsIdentifier.js | 49 +- .../reference/staticAsIdentifier.symbols | 31 +- .../reference/staticAsIdentifier.types | 27 + .../reference/staticIndexers.symbols | 1 + .../staticInstanceResolution5.symbols | 3 + .../reference/staticInstanceResolution5.types | 16 +- ...aticMembersUsingClassTypeParameter.symbols | 6 + ...staticMembersUsingClassTypeParameter.types | 18 +- ...aticMethodReferencingTypeArgument1.symbols | 3 + ...staticMethodReferencingTypeArgument1.types | 26 +- ...hodsReferencingClassTypeParameters.symbols | 1 + ...ethodsReferencingClassTypeParameters.types | 6 +- .../staticModifierAlreadySeen.errors.txt | 13 +- .../reference/staticModifierAlreadySeen.js | 4 +- .../staticModifierAlreadySeen.symbols | 6 +- .../reference/staticModifierAlreadySeen.types | 2 + .../staticPropertyNotInClassType.symbols | 1 + .../staticPropertyNotInClassType.types | 2 +- .../reference/strictModeReservedWord.symbols | 14 + .../reference/strictModeReservedWord.types | 16 +- .../strictOptionalProperties1.errors.txt | 23 + .../reference/strictOptionalProperties1.js | 38 + .../strictOptionalProperties1.symbols | 48 + .../reference/strictOptionalProperties1.types | 32 + .../tailRecursiveConditionalTypes.js | 49 + .../tailRecursiveConditionalTypes.symbols | 118 + .../tailRecursiveConditionalTypes.types | 53 + .../reference/templateLiteralTypes1.symbols | 4 + .../reference/templateLiteralTypes1.types | 2 +- .../reference/templateLiteralTypes2.symbols | 1 + .../templateLiteralTypes3.errors.txt | 66 +- .../reference/templateLiteralTypes3.js | 108 + .../reference/templateLiteralTypes3.symbols | 147 + .../reference/templateLiteralTypes3.types | 138 +- ....1(module=es2022,target=es2015).errors.txt | 90 + ...velAwait.1(module=es2022,target=es2015).js | 152 + ...ait.1(module=es2022,target=es2015).symbols | 143 + ...Await.1(module=es2022,target=es2015).types | 195 + ...velAwait.1(module=es2022,target=es2017).js | 152 + ...ait.1(module=es2022,target=es2017).symbols | 143 + ...Await.1(module=es2022,target=es2017).types | 195 + ....1(module=esnext,target=es2015).errors.txt | 12 +- ....1(module=system,target=es2015).errors.txt | 12 +- ...2.js => topLevelAwait.2(module=es2022).js} | 0 ...=> topLevelAwait.2(module=es2022).symbols} | 0 ...s => topLevelAwait.2(module=es2022).types} | 0 .../topLevelAwait.2(module=esnext).js | 10 + .../topLevelAwait.2(module=esnext).symbols | 11 + .../topLevelAwait.2(module=esnext).types | 11 + ...=> topLevelAwait.3(module=es2022).symbols} | 0 ...s => topLevelAwait.3(module=es2022).types} | 0 .../topLevelAwait.3(module=esnext).symbols | 10 + .../topLevelAwait.3(module=esnext).types | 10 + ...elAwaitErrors.1(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.1(module=es2022).js} | 0 ...LevelAwaitErrors.1(module=es2022).symbols} | 0 ...opLevelAwaitErrors.1(module=es2022).types} | 0 ...velAwaitErrors.1(module=esnext).errors.txt | 107 + .../topLevelAwaitErrors.1(module=esnext).js | 104 + ...pLevelAwaitErrors.1(module=esnext).symbols | 71 + ...topLevelAwaitErrors.1(module=esnext).types | 120 + ...lAwaitErrors.10(module=es2022).errors.txt} | 0 ... topLevelAwaitErrors.10(module=es2022).js} | 0 ...evelAwaitErrors.10(module=es2022).symbols} | 0 ...pLevelAwaitErrors.10(module=es2022).types} | 0 ...elAwaitErrors.10(module=esnext).errors.txt | 13 + .../topLevelAwaitErrors.10(module=esnext).js | 15 + ...LevelAwaitErrors.10(module=esnext).symbols | 14 + ...opLevelAwaitErrors.10(module=esnext).types | 14 + ...lAwaitErrors.12(module=es2022).errors.txt} | 0 ... topLevelAwaitErrors.12(module=es2022).js} | 0 ...evelAwaitErrors.12(module=es2022).symbols} | 0 ...pLevelAwaitErrors.12(module=es2022).types} | 0 ...elAwaitErrors.12(module=esnext).errors.txt | 12 + .../topLevelAwaitErrors.12(module=esnext).js | 10 + ...LevelAwaitErrors.12(module=esnext).symbols | 12 + ...opLevelAwaitErrors.12(module=esnext).types | 12 + ...elAwaitErrors.2(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.2(module=es2022).js} | 0 ...LevelAwaitErrors.2(module=es2022).symbols} | 0 ...opLevelAwaitErrors.2(module=es2022).types} | 0 ...velAwaitErrors.2(module=esnext).errors.txt | 11 + .../topLevelAwaitErrors.2(module=esnext).js | 11 + ...pLevelAwaitErrors.2(module=esnext).symbols | 7 + ...topLevelAwaitErrors.2(module=esnext).types | 8 + ...elAwaitErrors.3(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.3(module=es2022).js} | 0 ...LevelAwaitErrors.3(module=es2022).symbols} | 0 ...opLevelAwaitErrors.3(module=es2022).types} | 0 ...velAwaitErrors.3(module=esnext).errors.txt | 11 + .../topLevelAwaitErrors.3(module=esnext).js | 11 + ...pLevelAwaitErrors.3(module=esnext).symbols | 8 + ...topLevelAwaitErrors.3(module=esnext).types | 10 + ...elAwaitErrors.4(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.4(module=es2022).js} | 0 ...LevelAwaitErrors.4(module=es2022).symbols} | 0 ...opLevelAwaitErrors.4(module=es2022).types} | 0 ...velAwaitErrors.4(module=esnext).errors.txt | 11 + .../topLevelAwaitErrors.4(module=esnext).js | 11 + ...pLevelAwaitErrors.4(module=esnext).symbols | 7 + ...topLevelAwaitErrors.4(module=esnext).types | 9 + ...elAwaitErrors.5(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.5(module=es2022).js} | 0 ...LevelAwaitErrors.5(module=es2022).symbols} | 0 ...opLevelAwaitErrors.5(module=es2022).types} | 0 ...velAwaitErrors.5(module=esnext).errors.txt | 10 + .../topLevelAwaitErrors.5(module=esnext).js | 10 + ...pLevelAwaitErrors.5(module=esnext).symbols | 6 + ...topLevelAwaitErrors.5(module=esnext).types | 6 + ...elAwaitErrors.6(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.6(module=es2022).js} | 0 ...LevelAwaitErrors.6(module=es2022).symbols} | 0 ...opLevelAwaitErrors.6(module=es2022).types} | 0 ...velAwaitErrors.6(module=esnext).errors.txt | 10 + .../topLevelAwaitErrors.6(module=esnext).js | 10 + ...pLevelAwaitErrors.6(module=esnext).symbols | 6 + ...topLevelAwaitErrors.6(module=esnext).types | 6 + ...elAwaitErrors.7(module=es2022).errors.txt} | 3 +- ...> topLevelAwaitErrors.7(module=es2022).js} | 3 +- ...LevelAwaitErrors.7(module=es2022).symbols} | 0 ...opLevelAwaitErrors.7(module=es2022).types} | 0 ...velAwaitErrors.7(module=esnext).errors.txt | 13 + .../topLevelAwaitErrors.7(module=esnext).js | 15 + ...pLevelAwaitErrors.7(module=esnext).symbols | 13 + ...topLevelAwaitErrors.7(module=esnext).types | 13 + ...elAwaitErrors.8(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.8(module=es2022).js} | 0 ...LevelAwaitErrors.8(module=es2022).symbols} | 0 ...opLevelAwaitErrors.8(module=es2022).types} | 0 ...velAwaitErrors.8(module=esnext).errors.txt | 13 + .../topLevelAwaitErrors.8(module=esnext).js | 15 + ...pLevelAwaitErrors.8(module=esnext).symbols | 12 + ...topLevelAwaitErrors.8(module=esnext).types | 12 + ...elAwaitErrors.9(module=es2022).errors.txt} | 0 ...> topLevelAwaitErrors.9(module=es2022).js} | 0 ...LevelAwaitErrors.9(module=es2022).symbols} | 0 ...opLevelAwaitErrors.9(module=es2022).types} | 0 ...velAwaitErrors.9(module=esnext).errors.txt | 13 + .../topLevelAwaitErrors.9(module=esnext).js | 15 + ...pLevelAwaitErrors.9(module=esnext).symbols | 13 + ...topLevelAwaitErrors.9(module=esnext).types | 13 + ...lAwaitNonModule(module=es2022).errors.txt} | 0 ... topLevelAwaitNonModule(module=es2022).js} | 0 ...evelAwaitNonModule(module=es2022).symbols} | 0 ...pLevelAwaitNonModule(module=es2022).types} | 0 ...elAwaitNonModule(module=esnext).errors.txt | 20 + .../topLevelAwaitNonModule(module=esnext).js | 16 + ...LevelAwaitNonModule(module=esnext).symbols | 17 + ...opLevelAwaitNonModule(module=esnext).types | 21 + .../transitiveExportImports.baseline.jsonc | 493 + .../transitiveExportImports2.baseline.jsonc | 632 ++ ...> transitiveExportImports3.baseline.jsonc} | 1239 +-- ...ons module-kind is out-of-range.errors.txt | 4 +- ...nd is out-of-range.oldTranspile.errors.txt | 4 +- ...s target-script is out-of-range.errors.txt | 4 +- ...pt is out-of-range.oldTranspile.errors.txt | 4 +- .../reference/ts-expect-error.symbols | 4 + .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 1 + .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- .../tsconfig.json | 3 +- ...fiers-across-projects-resolve-correctly.js | 405 + .../files-containing-json-file.js | 2 +- .../initial-build/include-and-files.js | 2 +- ...r-include-and-file-name-matches-ts-file.js | 2 +- ...nclude-of-json-along-with-other-include.js | 2 +- .../initial-build/include-only.js | 2 +- .../initial-build/sourcemap.js | 2 +- .../sample1/initial-build/explainFiles.js | 14 +- ...t-correctly-with-cts-and-mts-extensions.js | 767 ++ ...project-with-extended-config-is-removed.js | 25 +- ...does-not-add-color-when-NO_COLOR-is-set.js | 4 +- ...-when-host-can't-provide-terminal-width.js | 4 +- ...tatus.DiagnosticsPresent_OutputsSkipped.js | 4 +- .../jsxImportSource-option-changed.js | 2 +- ...n-Windows-style-drive-root-is-lowercase.js | 4 +- ...n-Windows-style-drive-root-is-uppercase.js | 4 +- ...ry-symlink-target-and-import-match-disk.js | 4 +- ...le-symlink-target-and-import-match-disk.js | 4 +- ...target-matches-disk-but-import-does-not.js | 4 +- ...target-matches-disk-but-import-does-not.js | 4 +- ...link-target,-and-disk-are-all-different.js | 4 +- ...link-target,-and-disk-are-all-different.js | 4 +- ...link-target-agree-but-do-not-match-disk.js | 4 +- ...link-target-agree-but-do-not-match-disk.js | 4 +- ...k-but-directory-symlink-target-does-not.js | 4 +- ...s-disk-but-file-symlink-target-does-not.js | 4 +- ...ative-information-file-location-changes.js | 4 +- ...ImportSource-option-changed-incremental.js | 4 +- .../jsxImportSource-option-changed-watch.js | 4 +- ...iles-are-reflected-in-project-structure.js | 4 +- .../handle-recreated-files-correctly.js | 8 +- .../declarationDir-is-specified.js | 96 +- ...-outDir-and-declarationDir-is-specified.js | 96 +- .../when-outDir-is-specified.js | 96 +- .../with-outFile.js | 87 +- ...e-is-specified-with-declaration-enabled.js | 96 +- .../without-outDir-or-outFile-is-specified.js | 96 +- .../should-reflect-change-in-config-file.js | 6 +- ...er-old-one-without-file-being-in-config.js | 2 +- ...invoked,-ask-errors-on-it-after-old-one.js | 4 +- ...re-old-one-without-file-being-in-config.js | 2 +- ...nvoked,-ask-errors-on-it-before-old-one.js | 4 +- ...er-old-one-without-file-being-in-config.js | 2 +- ...invoked,-ask-errors-on-it-after-old-one.js | 4 +- ...re-old-one-without-file-being-in-config.js | 2 +- ...nvoked,-ask-errors-on-it-before-old-one.js | 4 +- ...nging-module-name-with-different-casing.js | 2 +- ...hen-renaming-file-with-different-casing.js | 2 +- ...-generated-when-the-config-file-changes.js | 2 +- ...when-the-config-file-doesnt-have-errors.js | 2 +- ...nerated-when-the-config-file-has-errors.js | 2 +- ...-file-opened-and-config-file-has-errors.js | 2 +- ...le-opened-and-doesnt-contain-any-errors.js | 2 +- ...rs-but-suppressDiagnosticEvents-is-true.js | 2 +- ...s-contains-the-project-reference-errors.js | 2 +- ...-same-ambient-module-and-is-also-module.js | 2 +- ...project-structure-and-reports-no-errors.js | 2 +- ...-when-timeout-occurs-after-installation.js | 4 +- ...n-timeout-occurs-inbetween-installation.js | 4 +- ...hen-json-is-root-file-found-by-tsconfig.js | 2 +- ...json-is-not-root-file-found-by-tsconfig.js | 2 +- ...-global-error-gerErr-with-sync-commands.js | 2 +- ...or-returns-includes-global-error-getErr.js | 2 +- ...-includes-global-error-geterrForProject.js | 2 +- ...large-file-size-is-determined-correctly.js | 2 +- ...t-is-not-open-gerErr-with-sync-commands.js | 2 +- ...n-dependency-project-is-not-open-getErr.js | 2 +- ...cy-project-is-not-open-geterrForProject.js | 2 +- ...-file-is-open-gerErr-with-sync-commands.js | 4 +- ...-when-the-depedency-file-is-open-getErr.js | 4 +- ...depedency-file-is-open-geterrForProject.js | 4 +- ...t-is-not-open-gerErr-with-sync-commands.js | 2 +- ...n-dependency-project-is-not-open-getErr.js | 2 +- ...cy-project-is-not-open-geterrForProject.js | 2 +- ...-file-is-open-gerErr-with-sync-commands.js | 4 +- ...-when-the-depedency-file-is-open-getErr.js | 4 +- ...depedency-file-is-open-geterrForProject.js | 4 +- .../ancestor-and-project-ref-management.js | 12 +- ...disableSourceOfProjectReferenceRedirect.js | 2 +- ...port-with-referenced-project-when-built.js | 2 +- .../auto-import-with-referenced-project.js | 2 +- ...ssfully-find-references-with-out-option.js | 6 +- ...indirect-project-but-not-in-another-one.js | 6 +- ...dProjectLoad-is-set-in-indirect-project.js | 6 +- ...oes-not-error-on-container-only-project.js | 6 +- ...-are-disabled-and-a-decl-map-is-missing.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- ...-are-disabled-and-a-decl-map-is-missing.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- ...-are-disabled-and-a-decl-map-is-missing.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- ...-are-disabled-and-a-decl-map-is-missing.js | 2 +- ...-are-disabled-and-a-decl-map-is-present.js | 2 +- ...s-are-enabled-and-a-decl-map-is-missing.js | 2 +- ...s-are-enabled-and-a-decl-map-is-present.js | 2 +- .../sibling-projects.js | 6 +- ...solution-is-built-with-preserveSymlinks.js | 2 +- ...-and-has-index.ts-and-solution-is-built.js | 2 +- ...tion-is-not-built-with-preserveSymlinks.js | 2 +- ...-has-index.ts-and-solution-is-not-built.js | 2 +- ...solution-is-built-with-preserveSymlinks.js | 2 +- ...th-scoped-package-and-solution-is-built.js | 2 +- ...tion-is-not-built-with-preserveSymlinks.js | 2 +- ...coped-package-and-solution-is-not-built.js | 2 +- ...solution-is-built-with-preserveSymlinks.js | 2 +- ...le-from-subFolder-and-solution-is-built.js | 2 +- ...tion-is-not-built-with-preserveSymlinks.js | 2 +- ...rom-subFolder-and-solution-is-not-built.js | 2 +- ...solution-is-built-with-preserveSymlinks.js | 2 +- ...th-scoped-package-and-solution-is-built.js | 2 +- ...tion-is-not-built-with-preserveSymlinks.js | 2 +- ...coped-package-and-solution-is-not-built.js | 2 +- ...disableSourceOfProjectReferenceRedirect.js | 8 +- ...ect-when-referenced-project-is-not-open.js | 4 +- ...disableSourceOfProjectReferenceRedirect.js | 12 +- ...project-when-referenced-project-is-open.js | 8 +- ...ject-is-directly-referenced-by-solution.js | 16 +- ...ct-is-indirectly-referenced-by-solution.js | 28 +- ...nced-project-and-using-declaration-maps.js | 6 +- ...ot-file-is-file-from-referenced-project.js | 6 +- ...indirect-project-but-not-in-another-one.js | 12 +- ...dProjectLoad-is-set-in-indirect-project.js | 12 +- ...-if-disableReferencedProjectLoad-is-set.js | 6 +- ...ces-open-file-through-project-reference.js | 26 +- ...ct-is-indirectly-referenced-by-solution.js | 38 +- ...nction-as-object-literal-property-types.js | 6 +- ...row-function-as-object-literal-property.js | 4 +- ...ss-when-using-arrow-function-assignment.js | 6 +- ...s-when-using-method-of-class-expression.js | 6 +- ...ness-when-using-object-literal-property.js | 6 +- ...cts-are-open-and-one-project-references.js | 16 +- ...ts-have-allowJs-and-emitDeclarationOnly.js | 2 +- ...ng-solution-and-siblings-are-not-loaded.js | 4 +- ...getting-project-from-orphan-script-info.js | 2 +- ...directory-watch-invoke-on-file-creation.js | 8 +- ...tion-when-project-compiles-from-sources.js | 4 +- ...s-in-typings-folder-and-then-recompiles.js | 2 +- ...mpiles-after-deleting-generated-folders.js | 4 +- ...ping-when-project-compiles-from-sources.js | 4 +- ...s-in-typings-folder-and-then-recompiles.js | 4 +- ...mpiles-after-deleting-generated-folders.js | 6 +- ...name-in-common-file-renames-all-project.js | 4 +- .../tsxFindAllReferences10.baseline.jsonc | 177 + .../tsxFindAllReferences2.baseline.jsonc | 98 + .../tsxFindAllReferences3.baseline.jsonc | 101 + .../tsxFindAllReferences7.baseline.jsonc | 120 + .../tsxFindAllReferences9.baseline.jsonc | 126 + ...drenInvalidType(target=es2015).errors.txt} | 0 ...preadChildrenInvalidType(target=es2015).js | 47 + ...hildrenInvalidType(target=es2015).symbols} | 0 ...dChildrenInvalidType(target=es2015).types} | 0 ...ChildrenInvalidType(target=es5).errors.txt | 38 + ...xSpreadChildrenInvalidType(target=es5).js} | 13 +- ...eadChildrenInvalidType(target=es5).symbols | 104 + ...preadChildrenInvalidType(target=es5).types | 108 + ...facesDifferingByTypeParameterName2.symbols | 1 + ...erfacesDifferingByTypeParameterName2.types | 2 +- .../reference/typeAssertions.symbols | 2 + .../baselines/reference/typeAssertions.types | 4 +- .../reference/typeCheckTypeArgument.symbols | 6 + .../reference/typeCheckTypeArgument.types | 10 +- .../reference/typeGuardFunctionErrors.symbols | 6 + .../reference/typeGuardFunctionErrors.types | 10 +- .../reference/typeLookupInIIFE.types | 2 +- .../typeParameterConstraints1.symbols | 1 + .../reference/typeParameterConstraints1.types | 2 +- ...eterUsedAsTypeParameterConstraint4.symbols | 10 + ...ameterUsedAsTypeParameterConstraint4.types | 34 +- ...metersAndParametersInComputedNames.symbols | 1 + .../typeParametersInStaticAccessors.symbols | 2 + .../typeParametersInStaticAccessors.types | 8 +- .../typeParametersInStaticMethods.symbols | 2 + .../typeParametersInStaticMethods.types | 10 +- .../typeParametersInStaticProperties.symbols | 1 + .../typeParametersInStaticProperties.types | 2 +- ...pePredicateOnVariableDeclaration02.symbols | 1 + ...typePredicateOnVariableDeclaration02.types | 2 +- tests/baselines/reference/typedefScope1.js | 2 +- tests/baselines/reference/typedefScope1.types | 2 +- .../reference/typedefTagTypeResolution.types | 8 +- .../reference/typeofClassWithPrivates.symbols | 1 + .../reference/typeofClassWithPrivates.types | 2 +- .../reference/typeofInternalModules.symbols | 1 + .../reference/typeofInternalModules.types | 2 +- tests/baselines/reference/umd2.symbols | 2 + tests/baselines/reference/umd2.types | 4 +- .../undeclaredModuleError.errors.txt | 4 +- .../reference/undeclaredModuleError.symbols | 4 +- .../reference/undeclaredModuleError.types | 12 +- .../reference/undefinedTypeArgument1.symbols | 1 + .../reference/undefinedTypeArgument1.types | 4 +- .../reference/undefinedTypeArgument2.symbols | 2 + .../reference/undefinedTypeArgument2.types | 6 +- .../unknownSymbolInGenericReturnType.symbols | 1 + .../unknownSymbolInGenericReturnType.types | 10 +- .../reference/unknownSymbols1.symbols | 6 + .../baselines/reference/unknownSymbols1.types | 14 +- .../reference/unknownSymbols2.symbols | 2 + .../baselines/reference/unknownSymbols2.types | 10 +- .../reference/unknownTypeArgOnCall.symbols | 1 + .../reference/unknownTypeErrors.symbols | 1 + .../reference/unknownTypeErrors.types | 2 +- .../unresolvedTypeAssertionSymbol.symbols | 1 + .../unresolvedTypeAssertionSymbol.types | 4 +- .../unspecializedConstraints.symbols | 1 + .../reference/unspecializedConstraints.types | 18 +- .../unusedInvalidTypeArguments.symbols | 2 + .../unusedInvalidTypeArguments.types | 2 +- .../unusedLocalsAndParameters.symbols | 1 + .../reference/unusedLocalsAndParameters.types | 6 +- ...atorResolvedDuringContextualTyping.symbols | 1 + ...aratorResolvedDuringContextualTyping.types | 4 +- .../reference/variadicTuples1.symbols | 3 + tests/baselines/reference/variance.symbols | 1 + tests/cases/compiler/awaitedType.ts | 161 + tests/cases/compiler/awaitedTypeStrictNull.ts | 61 + ...eVarianceBigArrayConstraintsPerformance.ts | 11 + .../constEnumPreserveEmitNamedExport1.ts | 12 + .../constEnumPreserveEmitNamedExport2.ts | 12 + tests/cases/compiler/deepComparisons.ts | 19 + .../cases/compiler/didYouMeanStringLiteral.ts | 7 + ...NeedToChangeYourTargetLibraryES2016Plus.ts | 2 +- .../genericCapturingFunctionNarrowing.ts | 13 + ...dToUnknownNotAssignableToConcreteObject.ts | 26 + tests/cases/compiler/importHelpersES6.ts | 2 + .../importHelpersNoHelpersForPrivateFields.ts | 16 + .../compiler/isolatedModulesReExportType.ts | 11 + tests/cases/compiler/jsdocTypeCast.ts | 21 + .../cases/compiler/keyRemappingKeyofResult.ts | 72 + tests/cases/compiler/libCompileChecks.ts | 7 + .../compiler/libTypeScriptOverrideSimple.ts | 9 + .../compiler/libTypeScriptSubfileResolving.ts | 11 + tests/cases/compiler/narrowByEquality.ts | 15 + tests/cases/compiler/parseInvalidNames.ts | 9 + .../compiler/recursiveConditionalTypes.ts | 12 +- tests/cases/compiler/staticAsIdentifier.ts | 15 + .../compiler/strictOptionalProperties1.ts | 23 + .../compiler/tailRecursiveConditionalTypes.ts | 30 + .../privateNames/privateNameInInExpression.ts | 119 + .../privateNameInInExpressionTransform.ts | 47 + .../privateNameInInExpressionUnused.ts | 13 + .../privateNamesIncompatibleModifiersJs.ts | 65 + .../controlFlow/assertionTypePredicates2.ts | 27 + .../controlFlow/controlFlowAliasing.ts | 10 + .../controlFlowAliasingCatchVariables.ts | 28 + .../controlFlow/controlFlowTypeofObject.ts | 71 + .../conformance/es2018/es2018IntlAPIs.ts | 7 + .../conformance/es2020/es2020IntlAPIs.ts | 45 + .../comparisonOperatorWithIntersectionType.ts | 5 + .../typeAssertions/constAssertionOnEnum.ts | 12 +- .../externalModules/topLevelAwait.1.ts | 2 +- .../externalModules/topLevelAwait.2.ts | 2 +- .../externalModules/topLevelAwait.3.ts | 4 +- .../externalModules/topLevelAwaitErrors.1.ts | 2 +- .../externalModules/topLevelAwaitErrors.10.ts | 2 +- .../externalModules/topLevelAwaitErrors.12.ts | 2 +- .../externalModules/topLevelAwaitErrors.2.ts | 2 +- .../externalModules/topLevelAwaitErrors.3.ts | 2 +- .../externalModules/topLevelAwaitErrors.4.ts | 2 +- .../externalModules/topLevelAwaitErrors.5.ts | 2 +- .../externalModules/topLevelAwaitErrors.6.ts | 2 +- .../externalModules/topLevelAwaitErrors.7.ts | 4 +- .../externalModules/topLevelAwaitErrors.8.ts | 2 +- .../externalModules/topLevelAwaitErrors.9.ts | 2 +- .../externalModules/topLevelAwaitNonModule.ts | 2 +- .../typeOnly/exportSpecifiers.ts | 21 + .../typeOnly/importSpecifiers1.ts | 46 + .../typeOnly/preserveValueImports.ts | 28 + .../typeOnly/preserveValueImports_errors.ts | 47 + ...erveValueImports_importsNotUsedAsValues.ts | 14 + .../preserveValueImports_mixedImports.ts | 13 + .../typeOnly/preserveValueImports_module.ts | 4 + .../importAssertion/importAssertion1.ts | 37 + .../importAssertion/importAssertion2.ts | 17 + .../importAssertion/importAssertion3.ts | 15 + .../jsdoc/jsdocTemplateTagDefault.ts | 71 + .../jsdoc/jsdocTemplateTagNameResolution.ts | 16 + .../jsx/inline/inlineJsxAndJsxFragPragma.tsx | 53 +- .../jsx/tsxSpreadChildrenInvalidType.tsx | 1 + .../allowJs/nodeAllowJsPackageSelfName.ts | 24 + .../node/allowJs/nodeModulesAllowJs1.ts | 324 + ...ModulesAllowJsConditionalPackageExports.ts | 126 + .../nodeModulesAllowJsDynamicImport.ts | 27 + .../nodeModulesAllowJsExportAssignment.ts | 32 + ...deModulesAllowJsGeneratedNameCollisions.ts | 29 + .../nodeModulesAllowJsImportAssignment.ts | 34 + ...eModulesAllowJsImportHelpersCollisions1.ts | 34 + ...eModulesAllowJsImportHelpersCollisions2.ts | 30 + ...eModulesAllowJsImportHelpersCollisions3.ts | 32 + .../allowJs/nodeModulesAllowJsImportMeta.ts | 23 + .../nodeModulesAllowJsPackageExports.ts | 92 + .../nodeModulesAllowJsPackageImports.ts | 41 + ...nodeModulesAllowJsPackagePatternExports.ts | 69 + ...lesAllowJsPackagePatternExportsTrailers.ts | 69 + ...nodeModulesAllowJsSynchronousCallErrors.ts | 37 + .../nodeModulesAllowJsTopLevelAwait.ts | 25 + tests/cases/conformance/node/nodeModules1.ts | 321 + ...odeModulesCjsFormatFileAlwaysHasDefault.ts | 19 + .../nodeModulesConditionalPackageExports.ts | 124 + ...tionEmitDynamicImportWithPackageExports.ts | 71 + ...odulesDeclarationEmitWithPackageExports.ts | 93 + .../node/nodeModulesDynamicImport.ts | 24 + .../node/nodeModulesExportAssignments.ts | 20 + ...ModulesExportsBlocksSpecifierResolution.ts | 27 + ...lesExportsSpecifierGenerationConditions.ts | 34 + ...ulesExportsSpecifierGenerationDirectory.ts | 29 + ...odulesExportsSpecifierGenerationPattern.ts | 29 + .../node/nodeModulesForbidenSyntax.ts | 67 + .../nodeModulesGeneratedNameCollisions.ts | 26 + .../node/nodeModulesImportAssignments.ts | 31 + .../nodeModulesImportHelpersCollisions.ts | 31 + .../nodeModulesImportHelpersCollisions2.ts | 27 + .../nodeModulesImportHelpersCollisions3.ts | 25 + .../conformance/node/nodeModulesImportMeta.ts | 20 + .../nodeModulesImportResolutionIntoExport.ts | 24 + .../nodeModulesImportResolutionNoCycle.ts | 24 + .../node/nodeModulesPackageExports.ts | 90 + .../node/nodeModulesPackageImports.ts | 38 + .../node/nodeModulesPackagePatternExports.ts | 67 + ...odeModulesPackagePatternExportsTrailers.ts | 67 + .../node/nodeModulesSynchronousCallErrors.ts | 34 + .../node/nodeModulesTopLevelAwait.ts | 22 + .../nodeModulesTypesVersionPackageExports.ts | 53 + .../conformance/node/nodePackageSelfName.ts | 21 + .../node/nodePackageSelfNameScoped.ts | 21 + .../types/literal/templateLiteralTypes3.ts | 54 + .../mapped/mappedTypeAsClauseRelationships.ts | 27 + .../types/mapped/mappedTypesArraysTuples.ts | 4 +- .../types/members/indexSignatures1.ts | 9 + tests/cases/fourslash/autoCloseFragment.ts | 59 + tests/cases/fourslash/autoCloseTag.ts | 8 + .../autoImport_node12_node_modules1.ts | 11 + ...ixClassExtendAbstractMethodWithLongName.ts | 2 +- .../codeFixSpellingCaseSensitive4.ts | 26 + .../codeFixSpellingPrivateNameInIn.ts | 19 + ...foreSemanticDiagnosticsInArrowFunction1.ts | 2 +- .../completionImportCallAssertion.ts | 13 + .../completionInNamedImportLocation.ts | 16 +- .../completionListForExportEquals.ts | 2 +- .../completionListForExportEquals2.ts | 2 +- .../completionListInExportClause01.ts | 8 +- .../completionListInExportClause02.ts | 2 +- .../completionListInExportClause03.ts | 2 +- .../completionListInImportClause01.ts | 16 +- .../completionListInImportClause02.ts | 2 +- .../completionListInImportClause03.ts | 2 +- .../completionListInImportClause04.ts | 2 +- .../completionListIsGlobalCompletion.ts | 5 +- tests/cases/fourslash/completionsInExport.ts | 11 +- .../fourslash/completionsInExport_invalid.ts | 2 +- .../completionsInExport_moduleBlock.ts | 11 +- .../fourslash/duplicatePackageServices.ts | 24 +- .../cases/fourslash/extractMethod_forAwait.ts | 2 +- .../findAllReferencesDynamicImport3.ts | 10 +- .../findAllReferencesJSDocFunctionThis.ts | 10 +- .../findAllReferencesOfConstructor.ts | 30 +- ...findAllReferencesUmdModuleAsGlobalConst.ts | 12 +- tests/cases/fourslash/findAllRefsBadImport.ts | 6 +- .../fourslash/findAllRefsClassExpression0.ts | 16 +- .../fourslash/findAllRefsClassExpression1.ts | 13 +- .../fourslash/findAllRefsClassExpression2.ts | 12 +- .../findAllRefsClassWithStaticThisAccess.ts | 9 +- .../fourslash/findAllRefsDefaultImport.ts | 10 +- ...indAllRefsDefaultImportThroughNamespace.ts | 12 +- .../cases/fourslash/findAllRefsDefinition.ts | 12 +- .../findAllRefsDestructureGeneric.ts | 12 +- .../fourslash/findAllRefsDestructureGetter.ts | 23 +- .../findAllRefsDestructureGetter2.ts | 18 +- .../fourslash/findAllRefsExportAsNamespace.ts | 14 +- .../findAllRefsExportConstEqualToClass.ts | 15 +- .../fourslash/findAllRefsExportEquals.ts | 15 +- .../findAllRefsForComputedProperties.ts | 12 +- .../findAllRefsForComputedProperties2.ts | 12 +- .../fourslash/findAllRefsForDefaultExport.ts | 12 +- .../findAllRefsForDefaultExport04.ts | 22 +- .../findAllRefsForDefaultExportAnonymous.ts | 14 +- .../findAllRefsForDefaultExport_anonymous.ts | 10 +- .../findAllRefsForDefaultExport_reExport.ts | 25 +- ...t_reExport_allowSyntheticDefaultImports.ts | 26 +- .../fourslash/findAllRefsForMappedType.ts | 8 +- tests/cases/fourslash/findAllRefsForModule.ts | 8 +- .../fourslash/findAllRefsForModuleGlobal.ts | 8 +- .../fourslash/findAllRefsForObjectSpread.ts | 20 +- ...lRefsForStaticInstanceMethodInheritance.ts | 32 +- ...efsForStaticInstancePropertyInheritance.ts | 32 +- ...dAllRefsForVariableInImplementsClause01.ts | 2 +- .../findAllRefsGlobalThisKeywordInModule.ts | 5 +- .../fourslash/findAllRefsImportDefault.ts | 16 +- .../fourslash/findAllRefsImportEquals.ts | 7 +- .../findAllRefsImportEqualsJsonFile.ts | 16 +- .../cases/fourslash/findAllRefsImportNamed.ts | 11 +- .../findAllRefsImportStarOfExportEquals.ts | 32 +- .../fourslash/findAllRefsInClassExpression.ts | 10 +- .../findAllRefsInheritedProperties3.ts | 44 +- .../findAllRefsInheritedProperties4.ts | 18 +- .../findAllRefsInheritedProperties5.ts | 16 +- .../fourslash/findAllRefsIsDefinition.ts | 29 + .../fourslash/findAllRefsJsDocTypeDef.ts | 4 +- ...lRefsObjectBindingElementPropertyName03.ts | 14 +- ...lRefsObjectBindingElementPropertyName04.ts | 16 +- ...lRefsObjectBindingElementPropertyName05.ts | 3 +- ...lRefsObjectBindingElementPropertyName06.ts | 20 +- ...lRefsObjectBindingElementPropertyName07.ts | 4 +- .../fourslash/findAllRefsOfConstructor.ts | 23 +- .../fourslash/findAllRefsOfConstructor2.ts | 23 +- .../findAllRefsOfConstructor_multipleFiles.ts | 28 +- .../findAllRefsOfConstructor_withModifier.ts | 7 +- .../fourslash/findAllRefsOnImportAliases.ts | 18 +- .../fourslash/findAllRefsOnImportAliases2.ts | 25 +- ...indAllRefsParameterPropertyDeclaration1.ts | 13 +- ...indAllRefsParameterPropertyDeclaration2.ts | 13 +- ...indAllRefsParameterPropertyDeclaration3.ts | 13 +- ...arameterPropertyDeclaration_inheritance.ts | 28 +- .../findAllRefsPrefixSuffixPreference.ts | 24 +- .../findAllRefsPrivateNameProperties.ts | 7 +- ...sPropertyContextuallyTypedByTypeParam01.ts | 10 +- .../fourslash/findAllRefsReExportLocal.ts | 20 +- ...findAllRefsReExportRightNameWrongSymbol.ts | 31 +- .../fourslash/findAllRefsReExportStar.ts | 11 +- .../fourslash/findAllRefsReExportStarAs.ts | 16 +- tests/cases/fourslash/findAllRefsReExports.ts | 57 +- .../cases/fourslash/findAllRefsReExports2.ts | 10 +- .../findAllRefsReExportsUseInImportType.ts | 19 +- ...efsRedeclaredPropertyInDerivedInterface.ts | 14 +- .../findAllRefsRenameImportWithSameName.ts | 13 +- .../cases/fourslash/findAllRefsRootSymbols.ts | 18 +- .../fourslash/findAllRefsUnionProperty.ts | 26 +- .../findAllRefsUnresolvedSymbols1.ts | 10 + .../findAllRefsUnresolvedSymbols2.ts | 12 + .../findAllRefsUnresolvedSymbols3.ts | 12 + ...dAllRefsWithShorthandPropertyAssignment.ts | 17 +- ...AllRefsWithShorthandPropertyAssignment2.ts | 17 +- .../cases/fourslash/findAllRefsWriteAccess.ts | 16 +- .../findAllRefs_importType_exportEquals.ts | 17 +- .../fourslash/findReferencesJSXTagName.ts | 14 +- tests/cases/fourslash/fourslash.ts | 9 +- ...OccurrencesIsDefinitionOfBindingPattern.ts | 11 +- .../getOccurrencesIsDefinitionOfExport.ts | 13 +- tests/cases/fourslash/hoverOverComment.ts | 2 +- .../importNameCodeFix_importType1.ts | 28 + .../importNameCodeFix_importType2.ts | 51 + .../importNameCodeFix_importType3.ts | 18 + .../importNameCodeFix_importType4.ts | 18 + .../fourslash/importStatementCompletions1.ts | 59 +- ...rtStatementCompletions_esModuleInterop1.ts | 3 + ...rtStatementCompletions_esModuleInterop2.ts | 3 + ...rtStatementCompletions_noPatternAmbient.ts | 5 +- .../importStatementCompletions_noSnippet.ts | 3 + .../importStatementCompletions_quotes.ts | 3 + .../importStatementCompletions_semicolons.ts | 3 + .../cases/fourslash/importTypeCompletions1.ts | 26 + .../cases/fourslash/importTypeCompletions2.ts | 20 + .../cases/fourslash/importTypeCompletions3.ts | 26 + .../cases/fourslash/importTypeCompletions4.ts | 27 + .../cases/fourslash/importTypeCompletions5.ts | 28 + .../cases/fourslash/importTypeCompletions6.ts | 28 + .../cases/fourslash/importTypeCompletions7.ts | 32 + .../cases/fourslash/importTypeCompletions8.ts | 26 + .../cases/fourslash/importTypeCompletions9.ts | 26 + .../cases/fourslash/inlayHintsShouldWork65.ts | 22 + .../jsxAttributeCompletionStyleAuto.ts | 89 + .../jsxAttributeCompletionStyleBraces.ts | 95 + .../jsxAttributeCompletionStyleDefault.ts | 75 + .../jsxAttributeCompletionStyleNoSnippet.ts | 75 + .../jsxAttributeCompletionStyleNone.ts | 75 + tests/cases/fourslash/localGetReferences.ts | 13 +- .../fourslash/moduleNodeNextAutoImport1.ts | 21 + .../fourslash/moduleNodeNextAutoImport2.ts | 21 + .../fourslash/moduleNodeNextAutoImport3.ts | 21 + .../fourslash/moduleNodeNextImportFix.ts | 27 + ...lesFileEditStillAllowsResolutionsToWork.ts | 19 + .../nodeModulesImportCompletions1.ts | 48 + ...referenceInParameterPropertyDeclaration.ts | 29 +- .../cases/fourslash/referencesBloomFilters.ts | 10 +- .../fourslash/referencesBloomFilters2.ts | 10 +- .../fourslash/referencesForClassMembers.ts | 27 +- ...esForClassMembersExtendingAbstractClass.ts | 27 +- ...cesForClassMembersExtendingGenericClass.ts | 27 +- ...ontextuallyTypedObjectLiteralProperties.ts | 18 +- ...ncesForContextuallyTypedUnionProperties.ts | 33 +- ...cesForContextuallyTypedUnionProperties2.ts | 16 +- .../referencesForDeclarationKeywords.ts | 121 +- .../referencesForExpressionKeywords.ts | 54 +- .../referencesForIllegalAssignment.ts | 12 +- .../referencesForInheritedProperties.ts | 17 +- .../referencesForInheritedProperties2.ts | 17 +- .../referencesForInheritedProperties5.ts | 27 +- .../referencesForInheritedProperties6.ts | 12 +- .../referencesForInheritedProperties7.ts | 30 +- .../referencesForInheritedProperties8.ts | 17 +- tests/cases/fourslash/referencesForLabel2.ts | 2 +- .../referencesForMergedDeclarations3.ts | 9 +- .../referencesForMergedDeclarations5.ts | 15 +- .../referencesForMergedDeclarations7.ts | 15 +- .../cases/fourslash/referencesForModifiers.ts | 43 +- .../cases/fourslash/referencesForNoContext.ts | 2 +- ...eferencesForNumericLiteralPropertyNames.ts | 10 +- .../cases/fourslash/referencesForOverrides.ts | 85 +- .../referencesForStatementKeywords.ts | 275 +- ...referencesForStringLiteralPropertyNames.ts | 12 +- ...eferencesForStringLiteralPropertyNames4.ts | 13 +- ...eferencesForStringLiteralPropertyNames5.ts | 13 +- ...eferencesForStringLiteralPropertyNames6.ts | 11 +- ...eferencesForStringLiteralPropertyNames7.ts | 13 +- .../fourslash/referencesForTypeKeywords.ts | 56 +- .../fourslash/referencesForUnionProperties.ts | 25 +- tests/cases/fourslash/referencesInComment.ts | 2 +- tests/cases/fourslash/renameDefaultImport.ts | 8 +- .../renameDefaultImportDifferentName.ts | 8 +- .../renameImportAndExportInDiffFiles.ts | 12 +- .../fourslash/renameImportOfExportEquals.ts | 17 +- .../fourslash/renameImportOfExportEquals2.ts | 28 +- .../cases/fourslash/renameImportOfReExport.ts | 13 +- .../fourslash/renameImportOfReExport2.ts | 15 +- tests/cases/fourslash/renameJsExports01.ts | 6 +- tests/cases/fourslash/renameJsExports02.ts | 12 +- tests/cases/fourslash/renameJsExports03.ts | 31 +- .../findAllRefsForStringLiteralTypes.ts | 16 +- .../server/formatTrimRemainingRangets | 13 + .../importStatementCompletions_pnpm1.ts | 3 + ...portStatementCompletions_pnpmTransitive.ts | 2 +- tests/cases/fourslash/server/references01.ts | 15 +- .../server/referencesInConfiguredProject.ts | 15 +- .../fourslash/transitiveExportImports.ts | 18 +- .../fourslash/transitiveExportImports2.ts | 14 +- .../fourslash/transitiveExportImports3.ts | 18 +- .../cases/fourslash/tsxFindAllReferences10.ts | 8 +- .../cases/fourslash/tsxFindAllReferences2.ts | 6 +- .../cases/fourslash/tsxFindAllReferences3.ts | 6 +- .../cases/fourslash/tsxFindAllReferences7.ts | 8 +- .../cases/fourslash/tsxFindAllReferences9.ts | 8 +- tests/cases/fourslash/tsxQuickInfo4.ts | 6 +- tests/cases/fourslash/tsxQuickInfo5.ts | 2 +- tests/cases/fourslash/tsxQuickInfo6.ts | 4 +- tests/cases/fourslash/tsxQuickInfo7.ts | 14 +- tests/cases/fourslash/tsxSignatureHelp1.ts | 4 +- tests/cases/fourslash/tsxSignatureHelp2.ts | 2 +- 2123 files changed, 165771 insertions(+), 20562 deletions(-) create mode 100644 src/compiler/transformers/module/node.ts create mode 100644 src/lib/es2021.intl.d.ts delete mode 100644 tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Initial star ignores tag.json delete mode 100644 tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.Initial star space ignores tag.json create mode 100644 tests/baselines/reference/assertionTypePredicates2.js create mode 100644 tests/baselines/reference/assertionTypePredicates2.symbols create mode 100644 tests/baselines/reference/assertionTypePredicates2.types create mode 100644 tests/baselines/reference/awaitedType.errors.txt create mode 100644 tests/baselines/reference/awaitedType.js create mode 100644 tests/baselines/reference/awaitedType.symbols create mode 100644 tests/baselines/reference/awaitedType.types create mode 100644 tests/baselines/reference/awaitedTypeStrictNull.errors.txt create mode 100644 tests/baselines/reference/awaitedTypeStrictNull.js create mode 100644 tests/baselines/reference/awaitedTypeStrictNull.symbols create mode 100644 tests/baselines/reference/awaitedTypeStrictNull.types delete mode 100644 tests/baselines/reference/bundledNodeDTSFailsWithOutFlag.js delete mode 100644 tests/baselines/reference/bundledNodeDTSFailsWithOutFlag.symbols delete mode 100644 tests/baselines/reference/bundledNodeDTSFailsWithOutFlag.types delete mode 100644 tests/baselines/reference/bundledNodeDTSPassesWithFlag.js delete mode 100644 tests/baselines/reference/bundledNodeDTSPassesWithFlag.symbols delete mode 100644 tests/baselines/reference/bundledNodeDTSPassesWithFlag.types delete mode 100644 tests/baselines/reference/bundledNodeDTSWithExports.js delete mode 100644 tests/baselines/reference/bundledNodeDTSWithExports.symbols delete mode 100644 tests/baselines/reference/bundledNodeDTSWithExports.types delete mode 100644 tests/baselines/reference/bundledNodeDTSWithScopedPackage.js delete mode 100644 tests/baselines/reference/bundledNodeDTSWithScopedPackage.symbols delete mode 100644 tests/baselines/reference/bundledNodeDTSWithScopedPackage.types create mode 100644 tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt delete mode 100644 tests/baselines/reference/commonMissingSemicolons.symbols delete mode 100644 tests/baselines/reference/commonMissingSemicolons.types create mode 100644 tests/baselines/reference/comparisonOperatorWithIntersectionType.errors.txt create mode 100644 tests/baselines/reference/comparisonOperatorWithIntersectionType.js create mode 100644 tests/baselines/reference/comparisonOperatorWithIntersectionType.symbols create mode 100644 tests/baselines/reference/comparisonOperatorWithIntersectionType.types create mode 100644 tests/baselines/reference/completionImportCallAssertion.baseline create mode 100644 tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.errors.txt create mode 100644 tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.js create mode 100644 tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.symbols create mode 100644 tests/baselines/reference/conditionalTypeVarianceBigArrayConstraintsPerformance.types delete mode 100644 tests/baselines/reference/constEnumNamespaceReferenceCausesNoImport.js delete mode 100644 tests/baselines/reference/constEnumNamespaceReferenceCausesNoImport.symbols delete mode 100644 tests/baselines/reference/constEnumNamespaceReferenceCausesNoImport.types create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport1.js create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport1.symbols create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport1.types create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport2.js create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport2.symbols create mode 100644 tests/baselines/reference/constEnumPreserveEmitNamedExport2.types create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=false).js create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=false).symbols create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=false).types create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=true).errors.txt create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=true).js create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=true).symbols create mode 100644 tests/baselines/reference/controlFlowAliasingCatchVariables(useunknownincatchvariables=true).types create mode 100644 tests/baselines/reference/controlFlowTypeofObject.errors.txt create mode 100644 tests/baselines/reference/controlFlowTypeofObject.js create mode 100644 tests/baselines/reference/controlFlowTypeofObject.symbols create mode 100644 tests/baselines/reference/controlFlowTypeofObject.types create mode 100644 tests/baselines/reference/deepComparisons.errors.txt create mode 100644 tests/baselines/reference/deepComparisons.js create mode 100644 tests/baselines/reference/deepComparisons.symbols create mode 100644 tests/baselines/reference/deepComparisons.types create mode 100644 tests/baselines/reference/didYouMeanStringLiteral.errors.txt create mode 100644 tests/baselines/reference/didYouMeanStringLiteral.js create mode 100644 tests/baselines/reference/didYouMeanStringLiteral.symbols create mode 100644 tests/baselines/reference/didYouMeanStringLiteral.types create mode 100644 tests/baselines/reference/duplicatePackageServices.baseline.jsonc delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall.js delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall.symbols delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall.types delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall2.js delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall2.symbols delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCall2.types delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.js delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.symbols delete mode 100644 tests/baselines/reference/emitCodeBeforeSuperCallWithDefineFields.types create mode 100644 tests/baselines/reference/emitHelpersWithLocalCollisions(module=es2022).js create mode 100644 tests/baselines/reference/emitHelpersWithLocalCollisions(module=node12).js create mode 100644 tests/baselines/reference/emitHelpersWithLocalCollisions(module=nodenext).js create mode 100644 tests/baselines/reference/es2018IntlAPIs.js create mode 100644 tests/baselines/reference/es2018IntlAPIs.symbols create mode 100644 tests/baselines/reference/es2018IntlAPIs.types create mode 100644 tests/baselines/reference/es2020IntlAPIs.js create mode 100644 tests/baselines/reference/es2020IntlAPIs.symbols create mode 100644 tests/baselines/reference/es2020IntlAPIs.types delete mode 100644 tests/baselines/reference/exportAsNamespace1_amd.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace1_amd.js delete mode 100644 tests/baselines/reference/exportAsNamespace1_amd.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace1_amd.types delete mode 100644 tests/baselines/reference/exportAsNamespace1_esnext.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace1_esnext.js delete mode 100644 tests/baselines/reference/exportAsNamespace1_esnext.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace1_esnext.types delete mode 100644 tests/baselines/reference/exportAsNamespace1_system.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace1_system.js delete mode 100644 tests/baselines/reference/exportAsNamespace1_system.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace1_system.types delete mode 100644 tests/baselines/reference/exportAsNamespace1_umd.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace1_umd.js delete mode 100644 tests/baselines/reference/exportAsNamespace1_umd.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace1_umd.types delete mode 100644 tests/baselines/reference/exportAsNamespace2_amd.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace2_amd.js delete mode 100644 tests/baselines/reference/exportAsNamespace2_amd.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace2_amd.types delete mode 100644 tests/baselines/reference/exportAsNamespace2_esnext.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace2_esnext.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace2_esnext.types delete mode 100644 tests/baselines/reference/exportAsNamespace2_system.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace2_system.js delete mode 100644 tests/baselines/reference/exportAsNamespace2_system.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace2_system.types delete mode 100644 tests/baselines/reference/exportAsNamespace2_umd.errors.txt delete mode 100644 tests/baselines/reference/exportAsNamespace2_umd.js delete mode 100644 tests/baselines/reference/exportAsNamespace2_umd.symbols delete mode 100644 tests/baselines/reference/exportAsNamespace2_umd.types create mode 100644 tests/baselines/reference/exportSpecifiers.errors.txt create mode 100644 tests/baselines/reference/exportSpecifiers.js create mode 100644 tests/baselines/reference/exportSpecifiers.symbols create mode 100644 tests/baselines/reference/exportSpecifiers.types create mode 100644 tests/baselines/reference/findAllReferencesDynamicImport3.baseline.jsonc create mode 100644 tests/baselines/reference/findAllReferencesJSDocFunctionThis.baseline.jsonc create mode 100644 tests/baselines/reference/findAllReferencesOfConstructor.baseline.jsonc create mode 100644 tests/baselines/reference/findAllReferencesUmdModuleAsGlobalConst.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsBadImport.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsClassExpression0.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsClassExpression1.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsClassExpression2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsClassWithStaticThisAccess.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDefaultImport.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDefaultImportThroughNamespace.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDefinition.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDestructureGeneric.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDestructureGetter.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsDestructureGetter2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsExportAsNamespace.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsExportConstEqualToClass.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsExportEquals.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForComputedProperties.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForComputedProperties2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExport.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExport04.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExportAnonymous.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExport_anonymous.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExport_reExport.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForMappedType.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForModule.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForModuleGlobal.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForObjectSpread.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForStaticInstanceMethodInheritance.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForStaticInstancePropertyInheritance.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForStringLiteralTypes.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsForVariableInImplementsClause01.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsGlobalThisKeywordInModule.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsImportDefault.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsImportEquals.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsImportEqualsJsonFile.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsImportNamed.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsImportStarOfExportEquals.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsInClassExpression.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsInheritedProperties3.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsInheritedProperties4.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsInheritedProperties5.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsIsDefinition.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsJsDocTypeDef.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsObjectBindingElementPropertyName03.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsObjectBindingElementPropertyName04.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsObjectBindingElementPropertyName05.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsObjectBindingElementPropertyName06.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsObjectBindingElementPropertyName07.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOfConstructor.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOfConstructor2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOfConstructor_multipleFiles.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOfConstructor_withModifier.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOnImportAliases.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsOnImportAliases2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsParameterPropertyDeclaration1.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsParameterPropertyDeclaration2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsParameterPropertyDeclaration3.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsParameterPropertyDeclaration_inheritance.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsPrefixSuffixPreference.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsPropertyContextuallyTypedByTypeParam01.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExportLocal.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExportRightNameWrongSymbol.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExportStar.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExportStarAs.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExports.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExports2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsReExportsUseInImportType.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsRedeclaredPropertyInDerivedInterface.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsRenameImportWithSameName.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsRootSymbols.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsUnionProperty.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsUnresolvedSymbols1.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsUnresolvedSymbols2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsUnresolvedSymbols3.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsWithShorthandPropertyAssignment.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsWithShorthandPropertyAssignment2.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefsWriteAccess.baseline.jsonc create mode 100644 tests/baselines/reference/findAllRefs_importType_exportEquals.baseline.jsonc create mode 100644 tests/baselines/reference/findReferencesJSXTagName.baseline.jsonc create mode 100644 tests/baselines/reference/genericCapturingFunctionNarrowing.js create mode 100644 tests/baselines/reference/genericCapturingFunctionNarrowing.symbols create mode 100644 tests/baselines/reference/genericCapturingFunctionNarrowing.types create mode 100644 tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt create mode 100644 tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.js create mode 100644 tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.symbols create mode 100644 tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.types create mode 100644 tests/baselines/reference/getOccurrencesIsDefinitionOfBindingPattern.baseline.jsonc create mode 100644 tests/baselines/reference/getOccurrencesIsDefinitionOfExport.baseline.jsonc create mode 100644 tests/baselines/reference/hoverOverComment.baseline.jsonc create mode 100644 tests/baselines/reference/importAssertion1(module=commonjs).errors.txt create mode 100644 tests/baselines/reference/importAssertion1(module=commonjs).js create mode 100644 tests/baselines/reference/importAssertion1(module=commonjs).symbols create mode 100644 tests/baselines/reference/importAssertion1(module=commonjs).types create mode 100644 tests/baselines/reference/importAssertion1(module=es2015).errors.txt create mode 100644 tests/baselines/reference/importAssertion1(module=es2015).js create mode 100644 tests/baselines/reference/importAssertion1(module=es2015).symbols create mode 100644 tests/baselines/reference/importAssertion1(module=es2015).types create mode 100644 tests/baselines/reference/importAssertion1(module=esnext).errors.txt create mode 100644 tests/baselines/reference/importAssertion1(module=esnext).js create mode 100644 tests/baselines/reference/importAssertion1(module=esnext).symbols create mode 100644 tests/baselines/reference/importAssertion1(module=esnext).types create mode 100644 tests/baselines/reference/importAssertion2(module=commonjs).errors.txt create mode 100644 tests/baselines/reference/importAssertion2(module=commonjs).js create mode 100644 tests/baselines/reference/importAssertion2(module=commonjs).symbols create mode 100644 tests/baselines/reference/importAssertion2(module=commonjs).types create mode 100644 tests/baselines/reference/importAssertion2(module=es2015).errors.txt create mode 100644 tests/baselines/reference/importAssertion2(module=es2015).js create mode 100644 tests/baselines/reference/importAssertion2(module=es2015).symbols create mode 100644 tests/baselines/reference/importAssertion2(module=es2015).types create mode 100644 tests/baselines/reference/importAssertion2(module=esnext).js create mode 100644 tests/baselines/reference/importAssertion2(module=esnext).symbols create mode 100644 tests/baselines/reference/importAssertion2(module=esnext).types create mode 100644 tests/baselines/reference/importAssertion3(module=es2015).errors.txt create mode 100644 tests/baselines/reference/importAssertion3(module=es2015).js create mode 100644 tests/baselines/reference/importAssertion3(module=es2015).symbols create mode 100644 tests/baselines/reference/importAssertion3(module=es2015).types create mode 100644 tests/baselines/reference/importAssertion3(module=esnext).errors.txt create mode 100644 tests/baselines/reference/importAssertion3(module=esnext).js create mode 100644 tests/baselines/reference/importAssertion3(module=esnext).symbols create mode 100644 tests/baselines/reference/importAssertion3(module=esnext).types create mode 100644 tests/baselines/reference/importHelpersNoHelpersForPrivateFields.errors.txt create mode 100644 tests/baselines/reference/importHelpersNoHelpersForPrivateFields.js create mode 100644 tests/baselines/reference/importHelpersNoHelpersForPrivateFields.symbols create mode 100644 tests/baselines/reference/importHelpersNoHelpersForPrivateFields.types create mode 100644 tests/baselines/reference/importSpecifiers1.errors.txt create mode 100644 tests/baselines/reference/importSpecifiers1.js create mode 100644 tests/baselines/reference/importSpecifiers1.symbols create mode 100644 tests/baselines/reference/importSpecifiers1.types create mode 100644 tests/baselines/reference/inlineJsxAndJsxFragPragma.errors.txt delete mode 100644 tests/baselines/reference/invalidTaggedTemplateEscapeSequences.errors.txt delete mode 100644 tests/baselines/reference/invalidTaggedTemplateEscapeSequences.js delete mode 100644 tests/baselines/reference/invalidTaggedTemplateEscapeSequences.symbols delete mode 100644 tests/baselines/reference/invalidTaggedTemplateEscapeSequences.types delete mode 100644 tests/baselines/reference/jsDocTags.baseline create mode 100644 tests/baselines/reference/jsdocTemplateTagDefault.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateTagDefault.js create mode 100644 tests/baselines/reference/jsdocTemplateTagDefault.symbols create mode 100644 tests/baselines/reference/jsdocTemplateTagDefault.types create mode 100644 tests/baselines/reference/jsdocTemplateTagNameResolution.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateTagNameResolution.js create mode 100644 tests/baselines/reference/jsdocTemplateTagNameResolution.symbols create mode 100644 tests/baselines/reference/jsdocTemplateTagNameResolution.types create mode 100644 tests/baselines/reference/jsdocTypeCast.errors.txt create mode 100644 tests/baselines/reference/jsdocTypeCast.js create mode 100644 tests/baselines/reference/jsdocTypeCast.symbols create mode 100644 tests/baselines/reference/jsdocTypeCast.types delete mode 100644 tests/baselines/reference/jsxFactoryAndFragment.errors.txt delete mode 100644 tests/baselines/reference/jsxFactoryAndFragment.js delete mode 100644 tests/baselines/reference/jsxFactoryAndFragment.symbols delete mode 100644 tests/baselines/reference/jsxFactoryAndFragment.types create mode 100644 tests/baselines/reference/keyRemappingKeyofResult.js create mode 100644 tests/baselines/reference/keyRemappingKeyofResult.symbols create mode 100644 tests/baselines/reference/keyRemappingKeyofResult.types create mode 100644 tests/baselines/reference/libCompileChecks.js create mode 100644 tests/baselines/reference/libCompileChecks.symbols create mode 100644 tests/baselines/reference/libCompileChecks.types create mode 100644 tests/baselines/reference/libTypeScriptOverrideSimple.errors.txt create mode 100644 tests/baselines/reference/libTypeScriptOverrideSimple.js create mode 100644 tests/baselines/reference/libTypeScriptOverrideSimple.symbols create mode 100644 tests/baselines/reference/libTypeScriptOverrideSimple.types create mode 100644 tests/baselines/reference/libTypeScriptSubfileResolving.errors.txt create mode 100644 tests/baselines/reference/libTypeScriptSubfileResolving.js create mode 100644 tests/baselines/reference/libTypeScriptSubfileResolving.symbols create mode 100644 tests/baselines/reference/libTypeScriptSubfileResolving.types create mode 100644 tests/baselines/reference/localGetReferences.baseline.jsonc create mode 100644 tests/baselines/reference/mappedTypeAsClauseRelationships.errors.txt create mode 100644 tests/baselines/reference/mappedTypeAsClauseRelationships.js create mode 100644 tests/baselines/reference/mappedTypeAsClauseRelationships.symbols create mode 100644 tests/baselines/reference/mappedTypeAsClauseRelationships.types create mode 100644 tests/baselines/reference/moduleNodeNextImportFix.baseline delete mode 100644 tests/baselines/reference/moduleResolutionNoTs.errors.txt delete mode 100644 tests/baselines/reference/moduleResolutionNoTs.js delete mode 100644 tests/baselines/reference/moduleResolutionNoTs.symbols delete mode 100644 tests/baselines/reference/moduleResolutionNoTs.types create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=node12).js create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=node12).symbols create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=node12).types create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=nodenext).js create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeAllowJsPackageSelfName(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModules1(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModules1(module=node12).js create mode 100644 tests/baselines/reference/nodeModules1(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModules1(module=node12).types create mode 100644 tests/baselines/reference/nodeModules1(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModules1(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModules1(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModules1(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJs1(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsConditionalPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsDynamicImport(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsExportAssignment(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsGeneratedNameCollisions(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportAssignment(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions1(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions2(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsImportMeta(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackageImports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsPackagePatternExportsTrailers(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesAllowJsTopLevelAwait(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesCjsFormatFileAlwaysHasDefault(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesConditionalPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitDynamicImportWithPackageExports.js create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitDynamicImportWithPackageExports.symbols create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitDynamicImportWithPackageExports.types create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesDeclarationEmitWithPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesDynamicImport(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesExportAssignments(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsBlocksSpecifierResolution(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationConditions(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationDirectory(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesExportsSpecifierGenerationPattern(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesForbidenSyntax(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesGeneratedNameCollisions(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportAssignments(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions2(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportHelpersCollisions3(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportMeta(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportResolutionIntoExport(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesImportResolutionNoCycle(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesPackageImports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesPackagePatternExportsTrailers(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesSynchronousCallErrors(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesTopLevelAwait(module=nodenext).types create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=node12).js create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=node12).symbols create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=node12).types create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=nodenext).js create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodeModulesTypesVersionPackageExports(module=nodenext).types create mode 100644 tests/baselines/reference/nodePackageSelfName(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodePackageSelfName(module=node12).js create mode 100644 tests/baselines/reference/nodePackageSelfName(module=node12).symbols create mode 100644 tests/baselines/reference/nodePackageSelfName(module=node12).types create mode 100644 tests/baselines/reference/nodePackageSelfName(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodePackageSelfName(module=nodenext).js create mode 100644 tests/baselines/reference/nodePackageSelfName(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodePackageSelfName(module=nodenext).types create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=node12).errors.txt create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=node12).js create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=node12).symbols create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=node12).types create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=nodenext).errors.txt create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=nodenext).js create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=nodenext).symbols create mode 100644 tests/baselines/reference/nodePackageSelfNameScoped(module=nodenext).types delete mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.errors.txt delete mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.js delete mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.symbols delete mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.types delete mode 100644 tests/baselines/reference/organizeImports/Unused_Empty.ts delete mode 100644 tests/baselines/reference/organizeImports/Unused_false_positive_export_shorthand.ts delete mode 100644 tests/baselines/reference/organizeImports/Unused_false_positive_shorthand_assignment.ts delete mode 100644 tests/baselines/reference/override16.js delete mode 100644 tests/baselines/reference/override16.symbols delete mode 100644 tests/baselines/reference/override16.types create mode 100644 tests/baselines/reference/parseInvalidNames.errors.txt create mode 100644 tests/baselines/reference/parseInvalidNames.js create mode 100644 tests/baselines/reference/parseInvalidNames.symbols create mode 100644 tests/baselines/reference/parseInvalidNames.types delete mode 100644 tests/baselines/reference/pathMappingBasedModuleResolution1_classic.errors.txt delete mode 100644 tests/baselines/reference/pathMappingBasedModuleResolution1_classic.symbols delete mode 100644 tests/baselines/reference/pathMappingBasedModuleResolution1_classic.trace.json delete mode 100644 tests/baselines/reference/pathMappingBasedModuleResolution1_classic.types create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=false).errors.txt create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=false).js create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=false).symbols create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=false).types create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=true).errors.txt create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=true).js create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=true).symbols create mode 100644 tests/baselines/reference/preserveValueImports(isolatedmodules=true).types create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=false).js create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=false).symbols create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=false).types create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=true).errors.txt create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=true).js create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=true).symbols create mode 100644 tests/baselines/reference/preserveValueImports_errors(isolatedmodules=true).types create mode 100644 tests/baselines/reference/preserveValueImports_importsNotUsedAsValues.js create mode 100644 tests/baselines/reference/preserveValueImports_importsNotUsedAsValues.symbols create mode 100644 tests/baselines/reference/preserveValueImports_importsNotUsedAsValues.types create mode 100644 tests/baselines/reference/preserveValueImports_mixedImports.errors.txt create mode 100644 tests/baselines/reference/preserveValueImports_mixedImports.js create mode 100644 tests/baselines/reference/preserveValueImports_mixedImports.symbols create mode 100644 tests/baselines/reference/preserveValueImports_mixedImports.types create mode 100644 tests/baselines/reference/preserveValueImports_module(module=amd).errors.txt rename tests/baselines/reference/{pathMappingBasedModuleResolution1_classic.js => preserveValueImports_module(module=amd).js} (54%) create mode 100644 tests/baselines/reference/preserveValueImports_module(module=commonjs).errors.txt create mode 100644 tests/baselines/reference/preserveValueImports_module(module=commonjs).js create mode 100644 tests/baselines/reference/preserveValueImports_module(module=es2015).js create mode 100644 tests/baselines/reference/preserveValueImports_module(module=system).errors.txt create mode 100644 tests/baselines/reference/preserveValueImports_module(module=system).js create mode 100644 tests/baselines/reference/privateNameInInExpression.errors.txt create mode 100644 tests/baselines/reference/privateNameInInExpression.js create mode 100644 tests/baselines/reference/privateNameInInExpression.symbols create mode 100644 tests/baselines/reference/privateNameInInExpression.types create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=es2020).errors.txt create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=es2020).js create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=es2020).symbols create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=es2020).types create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=esnext).errors.txt create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=esnext).js create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=esnext).symbols create mode 100644 tests/baselines/reference/privateNameInInExpressionTransform(target=esnext).types create mode 100644 tests/baselines/reference/privateNameInInExpressionUnused.errors.txt create mode 100644 tests/baselines/reference/privateNameInInExpressionUnused.js create mode 100644 tests/baselines/reference/privateNameInInExpressionUnused.symbols create mode 100644 tests/baselines/reference/privateNameInInExpressionUnused.types delete mode 100644 tests/baselines/reference/privateNameStaticFieldInitializer.js delete mode 100644 tests/baselines/reference/privateNameStaticFieldInitializer.symbols delete mode 100644 tests/baselines/reference/privateNameStaticFieldInitializer.types create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiersJs.errors.txt create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiersJs.js create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiersJs.symbols create mode 100644 tests/baselines/reference/privateNamesIncompatibleModifiersJs.types delete mode 100644 tests/baselines/reference/project/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs/amd/jsFileCompilationDifferentNamesNotSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationDifferentNamesSpecifiedWithAllowJs/amd/jsFileCompilationDifferentNamesSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameDTsSpecifiedWithAllowJs/amd/jsFileCompilationSameNameDTsSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameDTsSpecifiedWithAllowJs/node/jsFileCompilationSameNameDTsSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameFilesNotSpecifiedWithAllowJs/amd/jsFileCompilationSameNameFilesNotSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameFilesNotSpecifiedWithAllowJs/node/jsFileCompilationSameNameFilesNotSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameFilesSpecifiedWithAllowJs/amd/jsFileCompilationSameNameFilesSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/project/jsFileCompilationSameNameFilesSpecifiedWithAllowJs/node/jsFileCompilationSameNameFilesSpecifiedWithAllowJs.errors.txt delete mode 100644 tests/baselines/reference/quickInfoDisplayPartsVar.shims.baseline create mode 100644 tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt delete mode 100644 tests/baselines/reference/redefinedPararameterProperty.symbols delete mode 100644 tests/baselines/reference/redefinedPararameterProperty.types create mode 100644 tests/baselines/reference/referenceInParameterPropertyDeclaration.baseline.jsonc create mode 100644 tests/baselines/reference/references01.baseline.jsonc create mode 100644 tests/baselines/reference/referencesBloomFilters.baseline.jsonc create mode 100644 tests/baselines/reference/referencesBloomFilters2.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForClassMembers.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForClassMembersExtendingAbstractClass.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForClassMembersExtendingGenericClass.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForContextuallyTypedObjectLiteralProperties.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForContextuallyTypedUnionProperties.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForContextuallyTypedUnionProperties2.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForDeclarationKeywords.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForExpressionKeywords.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForIllegalAssignment.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties2.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties5.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties6.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties7.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForInheritedProperties8.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForLabel2.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForMergedDeclarations3.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForMergedDeclarations5.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForMergedDeclarations7.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForModifiers.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForNoContext.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForNumericLiteralPropertyNames.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForOverrides.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStatementKeywords.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStringLiteralPropertyNames.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStringLiteralPropertyNames4.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStringLiteralPropertyNames5.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStringLiteralPropertyNames6.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForStringLiteralPropertyNames7.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForTypeKeywords.baseline.jsonc create mode 100644 tests/baselines/reference/referencesForUnionProperties.baseline.jsonc create mode 100644 tests/baselines/reference/referencesInComment.baseline.jsonc create mode 100644 tests/baselines/reference/referencesInConfiguredProject.baseline.jsonc create mode 100644 tests/baselines/reference/renameDefaultImport.baseline.jsonc create mode 100644 tests/baselines/reference/renameDefaultImportDifferentName.baseline.jsonc create mode 100644 tests/baselines/reference/renameImportAndExportInDiffFiles.baseline.jsonc create mode 100644 tests/baselines/reference/renameImportOfExportEquals.baseline.jsonc create mode 100644 tests/baselines/reference/renameImportOfExportEquals2.baseline.jsonc create mode 100644 tests/baselines/reference/renameImportOfReExport.baseline.jsonc create mode 100644 tests/baselines/reference/renameImportOfReExport2.baseline.jsonc create mode 100644 tests/baselines/reference/renameJsExports01.baseline.jsonc create mode 100644 tests/baselines/reference/renameJsExports02.baseline.jsonc create mode 100644 tests/baselines/reference/renameJsExports03.baseline.jsonc delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/bundledPackageName/tsconfig.json delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/pedanticOverride/tsconfig.json create mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/preserveValueImports/tsconfig.json delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/project/tsconfig.json delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/strictAwaitedTypes/tsconfig.json delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/strictGeneratorTypes/tsconfig.json delete mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/strictOptionalProperties/tsconfig.json create mode 100644 tests/baselines/reference/tailRecursiveConditionalTypes.js create mode 100644 tests/baselines/reference/tailRecursiveConditionalTypes.symbols create mode 100644 tests/baselines/reference/tailRecursiveConditionalTypes.types create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2015).errors.txt create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2015).js create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2015).symbols create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2015).types create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2017).js create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2017).symbols create mode 100644 tests/baselines/reference/topLevelAwait.1(module=es2022,target=es2017).types rename tests/baselines/reference/{topLevelAwait.2.js => topLevelAwait.2(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwait.2.symbols => topLevelAwait.2(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwait.2.types => topLevelAwait.2(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwait.2(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwait.2(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwait.2(module=esnext).types rename tests/baselines/reference/{topLevelAwait.3.symbols => topLevelAwait.3(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwait.3.types => topLevelAwait.3(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwait.3(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwait.3(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.1.errors.txt => topLevelAwaitErrors.1(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.1.js => topLevelAwaitErrors.1(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.1.symbols => topLevelAwaitErrors.1(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.1.types => topLevelAwaitErrors.1(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.1(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.1(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.1(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.1(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.10.errors.txt => topLevelAwaitErrors.10(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.10.js => topLevelAwaitErrors.10(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.10.symbols => topLevelAwaitErrors.10(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.10.types => topLevelAwaitErrors.10(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.10(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.10(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.10(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.10(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.12.errors.txt => topLevelAwaitErrors.12(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.12.js => topLevelAwaitErrors.12(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.12.symbols => topLevelAwaitErrors.12(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.12.types => topLevelAwaitErrors.12(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.12(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.12(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.12(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.12(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.2.errors.txt => topLevelAwaitErrors.2(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.2.js => topLevelAwaitErrors.2(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.2.symbols => topLevelAwaitErrors.2(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.2.types => topLevelAwaitErrors.2(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.2(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.2(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.2(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.2(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.3.errors.txt => topLevelAwaitErrors.3(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.3.js => topLevelAwaitErrors.3(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.3.symbols => topLevelAwaitErrors.3(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.3.types => topLevelAwaitErrors.3(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.3(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.3(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.3(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.3(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.4.errors.txt => topLevelAwaitErrors.4(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.4.js => topLevelAwaitErrors.4(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.4.symbols => topLevelAwaitErrors.4(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.4.types => topLevelAwaitErrors.4(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.4(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.4(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.4(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.4(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.5.errors.txt => topLevelAwaitErrors.5(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.5.js => topLevelAwaitErrors.5(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.5.symbols => topLevelAwaitErrors.5(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.5.types => topLevelAwaitErrors.5(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.5(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.5(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.5(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.5(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.6.errors.txt => topLevelAwaitErrors.6(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.6.js => topLevelAwaitErrors.6(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.6.symbols => topLevelAwaitErrors.6(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.6.types => topLevelAwaitErrors.6(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.6(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.6(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.6(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.6(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.7.errors.txt => topLevelAwaitErrors.7(module=es2022).errors.txt} (91%) rename tests/baselines/reference/{topLevelAwaitErrors.7.js => topLevelAwaitErrors.7(module=es2022).js} (96%) rename tests/baselines/reference/{topLevelAwaitErrors.7.symbols => topLevelAwaitErrors.7(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.7.types => topLevelAwaitErrors.7(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.7(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.7(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.7(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.7(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.8.errors.txt => topLevelAwaitErrors.8(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.8.js => topLevelAwaitErrors.8(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.8.symbols => topLevelAwaitErrors.8(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.8.types => topLevelAwaitErrors.8(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.8(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.8(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.8(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.8(module=esnext).types rename tests/baselines/reference/{topLevelAwaitErrors.9.errors.txt => topLevelAwaitErrors.9(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.9.js => topLevelAwaitErrors.9(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.9.symbols => topLevelAwaitErrors.9(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitErrors.9.types => topLevelAwaitErrors.9(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitErrors.9(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitErrors.9(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitErrors.9(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitErrors.9(module=esnext).types rename tests/baselines/reference/{topLevelAwaitNonModule.errors.txt => topLevelAwaitNonModule(module=es2022).errors.txt} (100%) rename tests/baselines/reference/{topLevelAwaitNonModule.js => topLevelAwaitNonModule(module=es2022).js} (100%) rename tests/baselines/reference/{topLevelAwaitNonModule.symbols => topLevelAwaitNonModule(module=es2022).symbols} (100%) rename tests/baselines/reference/{topLevelAwaitNonModule.types => topLevelAwaitNonModule(module=es2022).types} (100%) create mode 100644 tests/baselines/reference/topLevelAwaitNonModule(module=esnext).errors.txt create mode 100644 tests/baselines/reference/topLevelAwaitNonModule(module=esnext).js create mode 100644 tests/baselines/reference/topLevelAwaitNonModule(module=esnext).symbols create mode 100644 tests/baselines/reference/topLevelAwaitNonModule(module=esnext).types create mode 100644 tests/baselines/reference/transitiveExportImports.baseline.jsonc create mode 100644 tests/baselines/reference/transitiveExportImports2.baseline.jsonc rename tests/baselines/reference/{quickInfoDisplayPartsVar.shims-pp.baseline => transitiveExportImports3.baseline.jsonc} (51%) create mode 100644 tests/baselines/reference/tsbuild/moduleSpecifiers/initial-build/synthesized-module-specifiers-across-projects-resolve-correctly.js create mode 100644 tests/baselines/reference/tsbuild/watchMode/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-cts-and-mts-extensions.js create mode 100644 tests/baselines/reference/tsxFindAllReferences10.baseline.jsonc create mode 100644 tests/baselines/reference/tsxFindAllReferences2.baseline.jsonc create mode 100644 tests/baselines/reference/tsxFindAllReferences3.baseline.jsonc create mode 100644 tests/baselines/reference/tsxFindAllReferences7.baseline.jsonc create mode 100644 tests/baselines/reference/tsxFindAllReferences9.baseline.jsonc rename tests/baselines/reference/{tsxSpreadChildrenInvalidType.errors.txt => tsxSpreadChildrenInvalidType(target=es2015).errors.txt} (100%) create mode 100644 tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js rename tests/baselines/reference/{tsxSpreadChildrenInvalidType.symbols => tsxSpreadChildrenInvalidType(target=es2015).symbols} (100%) rename tests/baselines/reference/{tsxSpreadChildrenInvalidType.types => tsxSpreadChildrenInvalidType(target=es2015).types} (100%) create mode 100644 tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt rename tests/baselines/reference/{tsxSpreadChildrenInvalidType.js => tsxSpreadChildrenInvalidType(target=es5).js} (66%) create mode 100644 tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols create mode 100644 tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types create mode 100644 tests/cases/compiler/awaitedType.ts create mode 100644 tests/cases/compiler/awaitedTypeStrictNull.ts create mode 100644 tests/cases/compiler/conditionalTypeVarianceBigArrayConstraintsPerformance.ts create mode 100644 tests/cases/compiler/constEnumPreserveEmitNamedExport1.ts create mode 100644 tests/cases/compiler/constEnumPreserveEmitNamedExport2.ts create mode 100644 tests/cases/compiler/deepComparisons.ts create mode 100644 tests/cases/compiler/didYouMeanStringLiteral.ts create mode 100644 tests/cases/compiler/genericCapturingFunctionNarrowing.ts create mode 100644 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts create mode 100644 tests/cases/compiler/importHelpersNoHelpersForPrivateFields.ts create mode 100644 tests/cases/compiler/jsdocTypeCast.ts create mode 100644 tests/cases/compiler/keyRemappingKeyofResult.ts create mode 100644 tests/cases/compiler/libCompileChecks.ts create mode 100644 tests/cases/compiler/libTypeScriptOverrideSimple.ts create mode 100644 tests/cases/compiler/libTypeScriptSubfileResolving.ts create mode 100644 tests/cases/compiler/parseInvalidNames.ts create mode 100644 tests/cases/compiler/tailRecursiveConditionalTypes.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInInExpression.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInInExpressionTransform.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameInInExpressionUnused.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNamesIncompatibleModifiersJs.ts create mode 100644 tests/cases/conformance/controlFlow/assertionTypePredicates2.ts create mode 100644 tests/cases/conformance/controlFlow/controlFlowAliasingCatchVariables.ts create mode 100644 tests/cases/conformance/controlFlow/controlFlowTypeofObject.ts create mode 100644 tests/cases/conformance/es2018/es2018IntlAPIs.ts create mode 100644 tests/cases/conformance/es2020/es2020IntlAPIs.ts create mode 100644 tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithIntersectionType.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/exportSpecifiers.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/importSpecifiers1.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/preserveValueImports.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/preserveValueImports_errors.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/preserveValueImports_importsNotUsedAsValues.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/preserveValueImports_mixedImports.ts create mode 100644 tests/cases/conformance/externalModules/typeOnly/preserveValueImports_module.ts create mode 100644 tests/cases/conformance/importAssertion/importAssertion1.ts create mode 100644 tests/cases/conformance/importAssertion/importAssertion2.ts create mode 100644 tests/cases/conformance/importAssertion/importAssertion3.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateTagDefault.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateTagNameResolution.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeAllowJsPackageSelfName.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJs1.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsConditionalPackageExports.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsDynamicImport.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsExportAssignment.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsGeneratedNameCollisions.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsImportAssignment.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsImportHelpersCollisions1.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsImportHelpersCollisions2.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsImportHelpersCollisions3.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsImportMeta.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackageExports.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackageImports.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExports.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsPackagePatternExportsTrailers.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsSynchronousCallErrors.ts create mode 100644 tests/cases/conformance/node/allowJs/nodeModulesAllowJsTopLevelAwait.ts create mode 100644 tests/cases/conformance/node/nodeModules1.ts create mode 100644 tests/cases/conformance/node/nodeModulesCjsFormatFileAlwaysHasDefault.ts create mode 100644 tests/cases/conformance/node/nodeModulesConditionalPackageExports.ts create mode 100644 tests/cases/conformance/node/nodeModulesDeclarationEmitDynamicImportWithPackageExports.ts create mode 100644 tests/cases/conformance/node/nodeModulesDeclarationEmitWithPackageExports.ts create mode 100644 tests/cases/conformance/node/nodeModulesDynamicImport.ts create mode 100644 tests/cases/conformance/node/nodeModulesExportAssignments.ts create mode 100644 tests/cases/conformance/node/nodeModulesExportsBlocksSpecifierResolution.ts create mode 100644 tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationConditions.ts create mode 100644 tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationDirectory.ts create mode 100644 tests/cases/conformance/node/nodeModulesExportsSpecifierGenerationPattern.ts create mode 100644 tests/cases/conformance/node/nodeModulesForbidenSyntax.ts create mode 100644 tests/cases/conformance/node/nodeModulesGeneratedNameCollisions.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportAssignments.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportHelpersCollisions.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportHelpersCollisions2.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportHelpersCollisions3.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportMeta.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportResolutionIntoExport.ts create mode 100644 tests/cases/conformance/node/nodeModulesImportResolutionNoCycle.ts create mode 100644 tests/cases/conformance/node/nodeModulesPackageExports.ts create mode 100644 tests/cases/conformance/node/nodeModulesPackageImports.ts create mode 100644 tests/cases/conformance/node/nodeModulesPackagePatternExports.ts create mode 100644 tests/cases/conformance/node/nodeModulesPackagePatternExportsTrailers.ts create mode 100644 tests/cases/conformance/node/nodeModulesSynchronousCallErrors.ts create mode 100644 tests/cases/conformance/node/nodeModulesTopLevelAwait.ts create mode 100644 tests/cases/conformance/node/nodeModulesTypesVersionPackageExports.ts create mode 100644 tests/cases/conformance/node/nodePackageSelfName.ts create mode 100644 tests/cases/conformance/node/nodePackageSelfNameScoped.ts create mode 100644 tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts create mode 100644 tests/cases/fourslash/autoCloseFragment.ts create mode 100644 tests/cases/fourslash/autoImport_node12_node_modules1.ts create mode 100644 tests/cases/fourslash/codeFixSpellingCaseSensitive4.ts create mode 100644 tests/cases/fourslash/codeFixSpellingPrivateNameInIn.ts create mode 100644 tests/cases/fourslash/completionImportCallAssertion.ts create mode 100644 tests/cases/fourslash/findAllRefsIsDefinition.ts create mode 100644 tests/cases/fourslash/findAllRefsUnresolvedSymbols1.ts create mode 100644 tests/cases/fourslash/findAllRefsUnresolvedSymbols2.ts create mode 100644 tests/cases/fourslash/findAllRefsUnresolvedSymbols3.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_importType1.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_importType2.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_importType3.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_importType4.ts create mode 100644 tests/cases/fourslash/importTypeCompletions1.ts create mode 100644 tests/cases/fourslash/importTypeCompletions2.ts create mode 100644 tests/cases/fourslash/importTypeCompletions3.ts create mode 100644 tests/cases/fourslash/importTypeCompletions4.ts create mode 100644 tests/cases/fourslash/importTypeCompletions5.ts create mode 100644 tests/cases/fourslash/importTypeCompletions6.ts create mode 100644 tests/cases/fourslash/importTypeCompletions7.ts create mode 100644 tests/cases/fourslash/importTypeCompletions8.ts create mode 100644 tests/cases/fourslash/importTypeCompletions9.ts create mode 100644 tests/cases/fourslash/inlayHintsShouldWork65.ts create mode 100644 tests/cases/fourslash/jsxAttributeCompletionStyleAuto.ts create mode 100644 tests/cases/fourslash/jsxAttributeCompletionStyleBraces.ts create mode 100644 tests/cases/fourslash/jsxAttributeCompletionStyleDefault.ts create mode 100644 tests/cases/fourslash/jsxAttributeCompletionStyleNoSnippet.ts create mode 100644 tests/cases/fourslash/jsxAttributeCompletionStyleNone.ts create mode 100644 tests/cases/fourslash/moduleNodeNextAutoImport1.ts create mode 100644 tests/cases/fourslash/moduleNodeNextAutoImport2.ts create mode 100644 tests/cases/fourslash/moduleNodeNextAutoImport3.ts create mode 100644 tests/cases/fourslash/moduleNodeNextImportFix.ts create mode 100644 tests/cases/fourslash/nodeModulesFileEditStillAllowsResolutionsToWork.ts create mode 100644 tests/cases/fourslash/nodeModulesImportCompletions1.ts create mode 100644 tests/cases/fourslash/server/formatTrimRemainingRangets diff --git a/.github/pr_owners.txt b/.github/pr_owners.txt index 6177279468b6d..7bd521dbdcd94 100644 --- a/.github/pr_owners.txt +++ b/.github/pr_owners.txt @@ -10,4 +10,5 @@ ahejlsberg amcasey jessetrinity minestarks -uniqueiniquity +armanio123 +gabritto diff --git a/.github/workflows/accept-baselines-fix-lints.yaml b/.github/workflows/accept-baselines-fix-lints.yaml index d92b1ae1836fd..0038167e35012 100644 --- a/.github/workflows/accept-baselines-fix-lints.yaml +++ b/.github/workflows/accept-baselines-fix-lints.yaml @@ -20,6 +20,7 @@ jobs: git config user.email "typescriptbot@microsoft.com" git config user.name "TypeScript Bot" npm install + git rm -r --quiet tests/baselines/reference :^tests/baselines/reference/docker :^tests/baselines/reference/user gulp runtests-parallel --ci --fix || true gulp baseline-accept git add ./src diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df96f73376b56..aefe86e2ef848 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [10.x, 12.x, 14.x] + node-version: [12.x, 14.x, 16.x] steps: - uses: actions/checkout@v2 diff --git a/lib/lib.es2021.d.ts b/lib/lib.es2021.d.ts index 1cb1e732ad858..74b5288d103b4 100644 --- a/lib/lib.es2021.d.ts +++ b/lib/lib.es2021.d.ts @@ -22,3 +22,4 @@ and limitations under the License. /// /// /// +/// diff --git a/package-lock.json b/package-lock.json index 3ccbfe3a702d5..a46acd0473d6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -279,9 +279,9 @@ } }, "@octokit/auth-token": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", - "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", "dev": true, "requires": { "@octokit/types": "^6.0.3" @@ -325,18 +325,18 @@ } }, "@octokit/openapi-types": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.1.1.tgz", - "integrity": "sha512-ygp/6r25Ezb1CJuVMnFfOsScEtPF0zosdTJDZ7mZ+I8IULl7DP1BS5ZvPRwglcarGPXOvS5sHdR0bjnVDDfQdQ==", + "version": "10.6.4", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.6.4.tgz", + "integrity": "sha512-JVmwWzYTIs6jACYOwD6zu5rdrqGIYsiAsLzTCxdrWIPNKNVjEF6vPTL20shmgJ4qZsq7WPBcLXLsaQD+NLChfg==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz", - "integrity": "sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ==", + "version": "2.16.7", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.7.tgz", + "integrity": "sha512-TMlyVhMPx6La1Ud4PSY4YxqAvb9YPEMs/7R1nBSbsw4wNqG73aBqls0r0dRRCWe5Pm0ZUGS9a94N46iAxlOR8A==", "dev": true, "requires": { - "@octokit/types": "^6.26.0" + "@octokit/types": "^6.31.3" } }, "@octokit/plugin-request-log": { @@ -346,19 +346,19 @@ "dev": true }, "@octokit/plugin-rest-endpoint-methods": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.0.tgz", - "integrity": "sha512-HiUZliq5wNg15cevJlTo9zDnPXAD0BMRhLxbRNPnq9J3HELKesDTOiou56ax2jC/rECUkK/uJTugrizYKSo/jg==", + "version": "5.11.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.11.4.tgz", + "integrity": "sha512-iS+GYTijrPUiEiLoDsGJhrbXIvOPfm2+schvr+FxNMs7PeE9Nl4bAMhE8ftfNX3Z1xLxSKwEZh0O7GbWurX5HQ==", "dev": true, "requires": { - "@octokit/types": "^6.27.0", + "@octokit/types": "^6.31.2", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.1.tgz", - "integrity": "sha512-Ls2cfs1OfXaOKzkcxnqw5MR6drMA/zWX/LIS/p8Yjdz7QKTPQLMsB3R+OvoxE6XnXeXEE2X7xe4G4l4X0gRiKQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", + "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", @@ -381,24 +381,24 @@ } }, "@octokit/rest": { - "version": "18.10.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.10.0.tgz", - "integrity": "sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw==", + "version": "18.11.4", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.11.4.tgz", + "integrity": "sha512-QplypCyYxqMK05JdMSm/bDWZO8VWWaBdzQ9tbF9rEV9rIEiICh+v6q+Vu/Y5hdze8JJaxfUC+PBC7vrnEkZvZg==", "dev": true, "requires": { "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.0", + "@octokit/plugin-paginate-rest": "^2.16.4", "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.9.0" + "@octokit/plugin-rest-endpoint-methods": "5.11.4" } }, "@octokit/types": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.27.0.tgz", - "integrity": "sha512-ha27f8DToxXBPEJdzHCCuqpw7AgKfjhWGdNf3yIlBAhAsaexBXTfWw36zNSsncALXGvJq4EjLy1p3Wz45Aqb4A==", + "version": "6.31.3", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.31.3.tgz", + "integrity": "sha512-IUG3uMpsLHrtEL6sCVXbxCgnbKcgpkS4K7gVEytLDvYYalkK3XcuMCHK1YPD8xJglSJAOAbL4MgXp47rS9G49w==", "dev": true, "requires": { - "@octokit/openapi-types": "^10.1.0" + "@octokit/openapi-types": "^10.6.4" } }, "@types/browserify": { @@ -412,9 +412,9 @@ } }, "@types/chai": { - "version": "4.2.21", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.21.tgz", - "integrity": "sha512-yd+9qKmJxm496BOV9CMNaey8TWsikaZOwMRwPHQIjcOJM9oV+fi9ZMNw3JsVnbEEbo2gRTDnGEBv8pjyn67hNg==", + "version": "4.2.22", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", + "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", "dev": true }, "@types/convert-source-map": { @@ -676,9 +676,9 @@ "dev": true }, "@types/node": { - "version": "16.7.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.12.tgz", - "integrity": "sha512-IrhrusVM9QJAn1xLFFqbZH+XCI8L6eZoVHjR4sZeGTBBvjQSuchXGgKpown1jP75TCMSndcbudYBDTekOhcIZA==", + "version": "16.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.2.tgz", + "integrity": "sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ==", "dev": true }, "@types/node-fetch": { @@ -1658,9 +1658,9 @@ } }, "is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -3490,9 +3490,9 @@ "dev": true }, "fast-safe-stringify": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", - "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, "fastq": { @@ -3771,6 +3771,16 @@ "has-symbols": "^1.0.1" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -3778,9 +3788,9 @@ "dev": true }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -4684,6 +4694,12 @@ "is-unc-path": "^1.0.0" } }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -4713,22 +4729,25 @@ }, "dependencies": { "es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -4841,6 +4860,15 @@ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", "dev": true }, + "is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -5311,16 +5339,16 @@ "dev": true }, "mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-0wE74YMgOkCgBUj8VyIDwmLUjTsS13WV1Pg7l0SHea2qzZzlq7MDnfbPsHKcELBRk3+izEVkRofjmClpycudCA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.2.tgz", + "integrity": "sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.2", - "debug": "4.3.1", + "debug": "4.3.2", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", @@ -5331,12 +5359,11 @@ "log-symbols": "4.1.0", "minimatch": "3.0.4", "ms": "2.1.3", - "nanoid": "3.1.23", + "nanoid": "3.1.25", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", - "wide-align": "1.1.3", "workerpool": "6.1.5", "yargs": "16.2.0", "yargs-parser": "20.2.4", @@ -5349,6 +5376,12 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -5408,9 +5441,9 @@ } }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -5474,6 +5507,20 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -5556,14 +5603,25 @@ } }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "supports-color": { @@ -5672,9 +5730,9 @@ } }, "is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -5722,9 +5780,9 @@ "optional": true }, "nanoid": { - "version": "3.1.23", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", - "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", "dev": true }, "nanomatch": { @@ -6162,6 +6220,12 @@ "sha.js": "^2.4.8" } }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -6226,82 +6290,20 @@ "dev": true }, "postcss": { - "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "picocolors": "^0.2.1", + "source-map": "^0.6.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -6995,9 +6997,9 @@ } }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -8044,22 +8046,25 @@ }, "dependencies": { "es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -8145,42 +8150,6 @@ } } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index fe5093903af98..31d9acb89763f 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "mkdirp": "latest", "mocha": "latest", "mocha-fivemat-progress-reporter": "latest", - "ms": "latest", + "ms": "^2.1.3", "node-fetch": "^2.6.1", "plugin-error": "latest", "pretty-hrtime": "^1.0.3", diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 96a35d5a4c77d..d26da9bcbf082 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2374,7 +2374,7 @@ namespace ts { function checkStrictModeLabeledStatement(node: LabeledStatement) { // Grammar checking for labeledStatement - if (inStrictMode && options.target! >= ScriptTarget.ES2015) { + if (inStrictMode && getEmitScriptTarget(options) >= ScriptTarget.ES2015) { if (isDeclarationStatement(node.statement) || isVariableStatement(node.statement)) { errorOnFirstToken(node.label, Diagnostics.A_label_is_not_allowed_here); } @@ -3388,7 +3388,7 @@ namespace ts { function bindTypeParameter(node: TypeParameterDeclaration) { if (isJSDocTemplateTag(node.parent)) { - const container = find((node.parent.parent as JSDoc).tags!, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217 + const container = getEffectiveContainerForJSDocTemplateTag(node.parent); if (container) { if (!container.locals) { container.locals = createSymbolTable(); diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 2b578cecfc035..aec8cae3cea12 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -258,6 +258,14 @@ namespace ts { Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size); state.seenAffectedFiles = state.seenAffectedFiles || new Set(); } + if (useOldState) { + // Any time the interpretation of a source file changes, mark it as changed + forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => { + if (state.fileInfos.has(sourceFilePath) && state.fileInfos.get(sourceFilePath)!.impliedFormat !== info.impliedFormat) { + state.changedFilesSet.add(sourceFilePath); + } + }); + } state.buildInfoEmitPending = !!state.changedFilesSet.size; return state; @@ -744,13 +752,13 @@ namespace ts { const actualSignature = signature ?? value.signature; return value.version === actualSignature ? value.affectsGlobalScope ? - { version: value.version, signature: undefined, affectsGlobalScope: true } : + { version: value.version, signature: undefined, affectsGlobalScope: true, impliedFormat: value.impliedFormat } : value.version : actualSignature !== undefined ? signature === undefined ? value : - { version: value.version, signature, affectsGlobalScope: value.affectsGlobalScope } : - { version: value.version, signature: false, affectsGlobalScope: value.affectsGlobalScope }; + { version: value.version, signature, affectsGlobalScope: value.affectsGlobalScope, impliedFormat: value.impliedFormat } : + { version: value.version, signature: false, affectsGlobalScope: value.affectsGlobalScope, impliedFormat: value.impliedFormat }; }); let referencedMap: ProgramBuildInfoReferencedMap | undefined; @@ -1243,10 +1251,10 @@ namespace ts { export function toBuilderStateFileInfo(fileInfo: ProgramBuildInfoFileInfo): BuilderState.FileInfo { return isString(fileInfo) ? - { version: fileInfo, signature: fileInfo, affectsGlobalScope: undefined } : + { version: fileInfo, signature: fileInfo, affectsGlobalScope: undefined, impliedFormat: undefined } : isString(fileInfo.signature) ? fileInfo as BuilderState.FileInfo : - { version: fileInfo.version, signature: fileInfo.signature === false ? undefined : fileInfo.version, affectsGlobalScope: fileInfo.affectsGlobalScope }; + { version: fileInfo.version, signature: fileInfo.signature === false ? undefined : fileInfo.version, affectsGlobalScope: fileInfo.affectsGlobalScope, impliedFormat: fileInfo.impliedFormat }; } export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo, buildInfoPath: string, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram { diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 6578962ebf0c8..a64a6c13ed1e8 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -82,6 +82,7 @@ namespace ts { readonly version: string; signature: string | undefined; affectsGlobalScope: boolean | undefined; + impliedFormat: number | undefined; } export interface ReadonlyManyToManyPathMap { @@ -332,7 +333,7 @@ namespace ts { } } } - fileInfos.set(sourceFile.resolvedPath, { version, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) || undefined }); + fileInfos.set(sourceFile.resolvedPath, { version, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) || undefined, impliedFormat: sourceFile.impliedNodeFormat }); } return { @@ -433,7 +434,7 @@ namespace ts { ); const firstDts = firstOrUndefined(emitOutput.outputFiles); if (firstDts) { - Debug.assert(fileExtensionIs(firstDts.name, Extension.Dts), "File extension for signature expected to be dts", () => `Found: ${getAnyExtensionFromPath(firstDts.name)} for ${firstDts.name}:: All output files: ${JSON.stringify(emitOutput.outputFiles.map(f => f.name))}`); + Debug.assert(fileExtensionIsOneOf(firstDts.name, [Extension.Dts, Extension.Dmts, Extension.Dcts]), "File extension for signature expected to be dts", () => `Found: ${getAnyExtensionFromPath(firstDts.name)} for ${firstDts.name}:: All output files: ${JSON.stringify(emitOutput.outputFiles.map(f => f.name))}`); latestSignature = (computeHash || generateDjb2Hash)(firstDts.text); if (exportedModulesMapCache && latestSignature !== prevSignature) { updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c47db65622e4..153f1feae6e59 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -197,6 +197,13 @@ namespace ts { InPropertyCheck = 1 << 4, } + const enum RecursionFlags { + None = 0, + Source = 1 << 0, + Target = 1 << 1, + Both = Source | Target, + } + const enum MappedTypeModifiers { IncludeReadonly = 1 << 0, ExcludeReadonly = 1 << 1, @@ -303,7 +310,7 @@ namespace ts { host.getSourceFiles().forEach(sf => { if (!sf.resolvedModules) return; - forEachEntry(sf.resolvedModules, r => { + sf.resolvedModules.forEach(r => { if (r && r.packageId) map.set(r.packageId.name, r.extension === Extension.Dts || !!map.get(r.packageId.name)); }); }); @@ -333,6 +340,7 @@ namespace ts { let totalInstantiationCount = 0; let instantiationCount = 0; let instantiationDepth = 0; + let inlineLevel = 0; let currentNode: Node | undefined; const emptySymbols = createSymbolTable(); @@ -720,6 +728,7 @@ namespace ts { getLocalTypeParametersOfClassOrInterfaceOrTypeAlias, isDeclarationVisible, isPropertyAccessible, + getTypeOnlyAliasDeclaration, getMemberOverrideModifierDiagnostic, }; @@ -748,14 +757,18 @@ namespace ts { const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); + const unresolvedSymbols = new Map(); + const errorTypes = new Map(); const anyType = createIntrinsicType(TypeFlags.Any, "any"); const autoType = createIntrinsicType(TypeFlags.Any, "any"); const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); const errorType = createIntrinsicType(TypeFlags.Any, "error"); + const unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); const nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType); const intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic"); const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); + const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined"); @@ -913,28 +926,30 @@ namespace ts { // and they will not get an error from not having unrelated library files let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined; let deferredGlobalESSymbolConstructorTypeSymbol: Symbol | undefined; - let deferredGlobalESSymbolType: ObjectType; + let deferredGlobalESSymbolType: ObjectType | undefined; let deferredGlobalTypedPropertyDescriptorType: GenericType; - let deferredGlobalPromiseType: GenericType; - let deferredGlobalPromiseLikeType: GenericType; + let deferredGlobalPromiseType: GenericType | undefined; + let deferredGlobalPromiseLikeType: GenericType | undefined; let deferredGlobalPromiseConstructorSymbol: Symbol | undefined; - let deferredGlobalPromiseConstructorLikeType: ObjectType; - let deferredGlobalIterableType: GenericType; - let deferredGlobalIteratorType: GenericType; - let deferredGlobalIterableIteratorType: GenericType; - let deferredGlobalGeneratorType: GenericType; - let deferredGlobalIteratorYieldResultType: GenericType; - let deferredGlobalIteratorReturnResultType: GenericType; - let deferredGlobalAsyncIterableType: GenericType; - let deferredGlobalAsyncIteratorType: GenericType; - let deferredGlobalAsyncIterableIteratorType: GenericType; - let deferredGlobalAsyncGeneratorType: GenericType; - let deferredGlobalTemplateStringsArrayType: ObjectType; + let deferredGlobalPromiseConstructorLikeType: ObjectType | undefined; + let deferredGlobalIterableType: GenericType | undefined; + let deferredGlobalIteratorType: GenericType | undefined; + let deferredGlobalIterableIteratorType: GenericType | undefined; + let deferredGlobalGeneratorType: GenericType | undefined; + let deferredGlobalIteratorYieldResultType: GenericType | undefined; + let deferredGlobalIteratorReturnResultType: GenericType | undefined; + let deferredGlobalAsyncIterableType: GenericType | undefined; + let deferredGlobalAsyncIteratorType: GenericType | undefined; + let deferredGlobalAsyncIterableIteratorType: GenericType | undefined; + let deferredGlobalAsyncGeneratorType: GenericType | undefined; + let deferredGlobalTemplateStringsArrayType: ObjectType | undefined; let deferredGlobalImportMetaType: ObjectType; let deferredGlobalImportMetaExpressionType: ObjectType; - let deferredGlobalExtractSymbol: Symbol; - let deferredGlobalOmitSymbol: Symbol; - let deferredGlobalBigIntType: ObjectType; + let deferredGlobalImportCallOptionsType: ObjectType | undefined; + let deferredGlobalExtractSymbol: Symbol | undefined; + let deferredGlobalOmitSymbol: Symbol | undefined; + let deferredGlobalAwaitedSymbol: Symbol | undefined; + let deferredGlobalBigIntType: ObjectType | undefined; const allPotentiallyUnusedIdentifiers = new Map(); // key is file name @@ -1029,17 +1044,9 @@ namespace ts { } } else { - if (file.localJsxNamespace) { - return file.localJsxNamespace; - } - const jsxPragma = file.pragmas.get("jsx"); - if (jsxPragma) { - const chosenPragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; - file.localJsxFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); - visitNode(file.localJsxFactory, markAsSynthetic); - if (file.localJsxFactory) { - return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText; - } + const localJsxNamespace = getLocalJsxNamespace(file); + if (localJsxNamespace) { + return file.localJsxNamespace = localJsxNamespace; } } } @@ -1061,13 +1068,28 @@ namespace ts { _jsxFactoryEntity = factory.createQualifiedName(factory.createIdentifier(unescapeLeadingUnderscores(_jsxNamespace)), "createElement"); } return _jsxNamespace; + } - function markAsSynthetic(node: Node): VisitResult { - setTextRangePosEnd(node, -1, -1); - return visitEachChild(node, markAsSynthetic, nullTransformationContext); + function getLocalJsxNamespace(file: SourceFile): __String | undefined { + if (file.localJsxNamespace) { + return file.localJsxNamespace; + } + const jsxPragma = file.pragmas.get("jsx"); + if (jsxPragma) { + const chosenPragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; + file.localJsxFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); + visitNode(file.localJsxFactory, markAsSynthetic); + if (file.localJsxFactory) { + return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText; + } } } + function markAsSynthetic(node: Node): VisitResult { + setTextRangePosEnd(node, -1, -1); + return visitEachChild(node, markAsSynthetic, nullTransformationContext); + } + function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) { // Ensure we have all the type information in place for this file so that all the // emitter questions of this resolver will return the right information. @@ -1520,7 +1542,7 @@ namespace ts { } else if (isParameterPropertyDeclaration(declaration, declaration.parent)) { // foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property - return !(compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields + return !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields && getContainingClass(declaration) === getContainingClass(usage) && isUsedInFunctionOrInstanceProperty(usage, declaration)); } @@ -1551,7 +1573,7 @@ namespace ts { return true; } if (isUsedInFunctionOrInstanceProperty(usage, declaration)) { - if (compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields + if (getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields && getContainingClass(declaration) && (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent))) { return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true); @@ -1743,9 +1765,8 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage | undefined, nameArg: __String | Identifier | undefined, isUse: boolean, - excludeGlobals = false, - issueSuggestions?: boolean): Symbol | undefined { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, issueSuggestions); + excludeGlobals = false): Symbol | undefined { + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol); } function resolveNameHelper( @@ -1756,7 +1777,7 @@ namespace ts { nameArg: __String | Identifier | undefined, isUse: boolean, excludeGlobals: boolean, - lookup: typeof getSymbol, issueSuggestions?: boolean): Symbol | undefined { + lookup: typeof getSymbol): Symbol | undefined { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location let result: Symbol | undefined; let lastLocation: Node | undefined; @@ -1829,7 +1850,7 @@ namespace ts { isInExternalModule = true; // falls through case SyntaxKind.ModuleDeclaration: - const moduleExports = getSymbolOfNode(location as SourceFile | ModuleDeclaration).exports || emptySymbols; + const moduleExports = getSymbolOfNode(location as SourceFile | ModuleDeclaration)?.exports || emptySymbols; if (location.kind === SyntaxKind.SourceFile || (isModuleDeclaration(location) && location.flags & NodeFlags.Ambient && !isGlobalScopeAugmentation(location))) { // It's an external module. First see if the module has an export default and if the local @@ -1872,7 +1893,7 @@ namespace ts { } break; case SyntaxKind.EnumDeclaration: - if (result = lookup(getSymbolOfNode(location)!.exports!, name, meaning & SymbolFlags.EnumMember)) { + if (result = lookup(getSymbolOfNode(location)?.exports || emptySymbols, name, meaning & SymbolFlags.EnumMember)) { break loop; } break; @@ -1955,7 +1976,7 @@ namespace ts { case SyntaxKind.ArrowFunction: // when targeting ES6 or higher there is no 'arguments' in an arrow function // for lower compile targets the resolved symbol is used to emit an error - if (compilerOptions.target! >= ScriptTarget.ES2015) { + if (getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015) { break; } // falls through @@ -2053,7 +2074,9 @@ namespace ts { lastSelfReferenceLocation = location; } lastLocation = location; - location = location.parent; + location = isJSDocTemplateTag(location) ? + getEffectiveContainerForJSDocTemplateTag(location) || location.parent : + location.parent; } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. @@ -2093,7 +2116,7 @@ namespace ts { !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { let suggestion: Symbol | undefined; - if (issueSuggestions && suggestionCount < maximumSuggestionCount) { + if (suggestionCount < maximumSuggestionCount) { suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning); const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration); if (isGlobalScopeAugmentationDeclaration) { @@ -2102,10 +2125,11 @@ namespace ts { if (suggestion) { const suggestionName = symbolToString(suggestion); const isUncheckedJS = isUncheckedJSSuggestion(originalLocation, suggestion, /*excludeClasses*/ false); - const message = isUncheckedJS ? Diagnostics.Could_not_find_name_0_Did_you_mean_1 : Diagnostics.Cannot_find_name_0_Did_you_mean_1; + const message = meaning === SymbolFlags.Namespace || nameArg && typeof nameArg !== "string" && nodeIsSynthesized(nameArg) ? Diagnostics.Cannot_find_namespace_0_Did_you_mean_1 + : isUncheckedJS ? Diagnostics.Could_not_find_name_0_Did_you_mean_1 + : Diagnostics.Cannot_find_name_0_Did_you_mean_1; const diagnostic = createError(errorLocation, message, diagnosticName(nameArg!), suggestionName); addErrorOrSuggestion(!isUncheckedJS, diagnostic); - if (suggestion.valueDeclaration) { addRelatedInfo( diagnostic, @@ -2133,7 +2157,7 @@ namespace ts { // Perform extra checks only if error reporting was requested if (nameNotFoundMessage) { - if (propertyWithInvalidInitializer && !(compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields)) { + if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) { // We have a match, but the reference occurred within a property initializer and the identifier also binds // to a local variable in the constructor where the code will be emitted. Note that this is actually allowed // with ESNext+useDefineForClassFields because the scope semantics are different. @@ -2195,21 +2219,28 @@ namespace ts { if (!isValidTypeOnlyAliasUseSite(useSite)) { const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol); if (typeOnlyDeclaration) { - const isExport = typeOnlyDeclarationIsExport(typeOnlyDeclaration); - const message = isExport + const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier ? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type : Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type; - const relatedMessage = isExport - ? Diagnostics._0_was_exported_here - : Diagnostics._0_was_imported_here; const unescapedName = unescapeLeadingUnderscores(name); - addRelatedInfo( + addTypeOnlyDeclarationRelatedInfo( error(useSite, message, unescapedName), - createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, unescapedName)); + typeOnlyDeclaration, + unescapedName); } } } + function addTypeOnlyDeclarationRelatedInfo(diagnostic: Diagnostic, typeOnlyDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, unescapedName: string) { + if (!typeOnlyDeclaration) return diagnostic; + return addRelatedInfo( + diagnostic, + createDiagnosticForNode( + typeOnlyDeclaration, + typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier ? Diagnostics._0_was_exported_here : Diagnostics._0_was_imported_here, + unescapedName)); + } + function getIsDeferredContext(location: Node, lastLocation: Node | undefined): boolean { if (location.kind !== SyntaxKind.ArrowFunction && location.kind !== SyntaxKind.FunctionExpression) { // initializers in instance property declaration of class like entities are executed in constructor and thus deferred @@ -2574,7 +2605,7 @@ namespace ts { function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ImportEqualsDeclaration, resolved: Symbol | undefined) { if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false) && !node.isTypeOnly) { const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node))!; - const isExport = typeOnlyDeclarationIsExport(typeOnlyDeclaration); + const isExport = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier; const message = isExport ? Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type : Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type; @@ -2582,9 +2613,7 @@ namespace ts { ? Diagnostics._0_was_exported_here : Diagnostics._0_was_imported_here; - // Non-null assertion is safe because the optionality comes from ImportClause, - // but if an ImportClause was the typeOnlyDeclaration, it had to have a `name`. - const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name!.escapedText); + const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText); addRelatedInfo(error(node.moduleReference, message), createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name)); } } @@ -2601,7 +2630,23 @@ namespace ts { return ((isExportAssignment(node) && !node.isExportEquals) || hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node)); } - function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) { + function getUsageModeForExpression(usage: Expression) { + return isStringLiteralLike(usage) ? getModeForUsageLocation(getSourceFileOfNode(usage), usage) : undefined; + } + + function isESMFormatImportImportingCommonjsFormatFile(usageMode: SourceFile["impliedNodeFormat"], targetMode: SourceFile["impliedNodeFormat"]) { + return usageMode === ModuleKind.ESNext && targetMode === ModuleKind.CommonJS; + } + + function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean, usage: Expression) { + const usageMode = file && getUsageModeForExpression(usage); + if (file && usageMode !== undefined) { + const result = isESMFormatImportImportingCommonjsFormatFile(usageMode, file.impliedNodeFormat); + if (usageMode === ModuleKind.ESNext || result) { + return result; + } + // fallthrough on cjs usages so we imply defaults for interop'd imports, too + } if (!allowSyntheticDefaultImports) { return false; } @@ -2644,7 +2689,7 @@ namespace ts { } const file = moduleSymbol.declarations?.find(isSourceFile); - const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias); + const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); if (!exportDefaultSymbol && !hasSyntheticDefault) { if (hasExportAssignmentSymbol(moduleSymbol)) { const compilerOptionName = moduleKind >= ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; @@ -2774,7 +2819,7 @@ namespace ts { if (!isIdentifier(name)) { return undefined; } - const suppressInteropError = name.escapedText === InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || compilerOptions.esModuleInterop); + const suppressInteropError = name.escapedText === InternalSymbolName.Default && !!(compilerOptions.allowSyntheticDefaultImports || getESModuleInterop(compilerOptions)); const targetSymbol = resolveESModuleSymbol(moduleSymbol, moduleSpecifier, /*dontResolveAlias*/ false, suppressInteropError); if (targetSymbol) { if (name.escapedText) { @@ -2796,7 +2841,7 @@ namespace ts { let symbolFromModule = getExportOfModule(targetSymbol, name, specifier, dontResolveAlias); if (symbolFromModule === undefined && name.escapedText === InternalSymbolName.Default) { const file = moduleSymbol.declarations?.find(isSourceFile); - if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, moduleSpecifier)) { symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } } @@ -2863,18 +2908,18 @@ namespace ts { function reportInvalidImportEqualsExportMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleName: string) { if (moduleKind >= ModuleKind.ES2015) { - const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_a_default_import : + const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_a_default_import : Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName); } else { if (isInJSFile(node)) { - const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import : + const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import : Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName); } else { - const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import : + const message = getESModuleInterop(compilerOptions) ? Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import : Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import; error(name, message, declarationName, declarationName, moduleName); } @@ -3038,13 +3083,13 @@ namespace ts { * and issue an error if so. * * @param aliasDeclaration The alias declaration not marked as type-only + * @param immediateTarget The symbol to which the alias declaration immediately resolves + * @param finalTarget The symbol to which the alias declaration ultimately resolves + * @param overwriteEmpty Checks `resolvesToSymbol` for type-only declarations even if `aliasDeclaration` * has already been marked as not resolving to a type-only alias. Used when recursively resolving qualified * names of import aliases, e.g. `import C = a.b.C`. If namespace `a` is not found to be type-only, the * import declaration will initially be marked as not resolving to a type-only symbol. But, namespace `b` * must still be checked for a type-only marker, overwriting the previous negative result if found. - * @param immediateTarget The symbol to which the alias declaration immediately resolves - * @param finalTarget The symbol to which the alias declaration ultimately resolves - * @param overwriteEmpty Checks `resolvesToSymbol` for type-only declarations even if `aliasDeclaration` */ function markSymbolOfAliasDeclarationIfTypeOnly( aliasDeclaration: Declaration | undefined, @@ -3078,7 +3123,7 @@ namespace ts { } /** Indicates that a symbol directly or indirectly resolves to a type-only import or export. */ - function getTypeOnlyAliasDeclaration(symbol: Symbol): TypeOnlyCompatibleAliasDeclaration | undefined { + function getTypeOnlyAliasDeclaration(symbol: Symbol): TypeOnlyAliasDeclaration | undefined { if (!(symbol.flags & SymbolFlags.Alias)) { return undefined; } @@ -3194,7 +3239,7 @@ namespace ts { if (name.kind === SyntaxKind.Identifier) { const message = meaning === namespaceMeaning || nodeIsSynthesized(name) ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name)); const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined; - symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true)); + symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true, false)); if (!symbol) { return getMergedSymbol(symbolFromJSPrototype); } @@ -3364,7 +3409,15 @@ namespace ts { return ambientModule; } const currentSourceFile = getSourceFileOfNode(location); - const resolvedModule = getResolvedModule(currentSourceFile, moduleReference)!; // TODO: GH#18217 + const contextSpecifier = isStringLiteralLike(location) + ? location + : findAncestor(location, isImportCall)?.arguments[0] || + findAncestor(location, isImportDeclaration)?.moduleSpecifier || + findAncestor(location, isExternalModuleImportEqualsDeclaration)?.moduleReference.expression || + findAncestor(location, isExportDeclaration)?.moduleSpecifier || + (isModuleDeclaration(location) ? location : location.parent && isModuleDeclaration(location.parent) && location.parent.name === location ? location.parent : undefined)?.name || + (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; + const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : undefined)!; // TODO: GH#18217 const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); const sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName); if (sourceFile) { @@ -3372,6 +3425,12 @@ namespace ts { if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference); } + if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) { + const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration); + if (isSyncImport && sourceFile.impliedNodeFormat === ModuleKind.ESNext) { + error(errorNode, Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_synchronously_Use_dynamic_import_instead, moduleReference); + } + } // merged symbol is module declaration symbol combined with all augmentations return getMergedSymbol(sourceFile.symbol); } @@ -3433,15 +3492,14 @@ namespace ts { * Direct users to import source with .js extension if outputting an ES module. * @see https://github.com/microsoft/TypeScript/issues/42151 */ - const moduleKind = getEmitModuleKind(compilerOptions); if (moduleKind >= ModuleKind.ES2015) { - replacedImportSource += ".js"; + replacedImportSource += tsExtension === Extension.Mts ? ".mjs" : tsExtension === Extension.Cts ? ".cjs" : ".js"; } error(errorNode, diag, tsExtension, replacedImportSource); } else if (!compilerOptions.resolveJsonModule && fileExtensionIs(moduleReference, Extension.Json) && - getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && + getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && hasJsonModuleEmitEnabled(compilerOptions)) { error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } @@ -3534,7 +3592,7 @@ namespace ts { return symbol; } - if (compilerOptions.esModuleInterop) { + if (getESModuleInterop(compilerOptions)) { const referenceParent = referencingLocation.parent; if ( (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) || @@ -3546,7 +3604,7 @@ namespace ts { sigs = getSignaturesOfStructuredType(type, SignatureKind.Construct); } if (sigs && sigs.length) { - const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol!); + const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol!, isImportCall(referenceParent) ? referenceParent.arguments[0] : referenceParent.moduleSpecifier); // Create a new symbol which has the module's type less the call and construct signatures const result = createSymbol(symbol.flags, symbol.escapedName); result.declarations = symbol.declarations ? symbol.declarations.slice() : []; @@ -4508,7 +4566,9 @@ namespace ts { const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation; const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0), writer); if (typeNode === undefined) return Debug.fail("should always get typenode"); - const options = { removeComments: true }; + // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. + // Otherwise, we always strip comments out. + const options = { removeComments: type !== unresolvedType }; const printer = createPrinter(options); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); @@ -4585,6 +4645,7 @@ namespace ts { isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName), fileExists: fileName => host.fileExists(fileName), getFileIncludeReasons: () => host.getFileIncludeReasons(), + readFile: host.readFile ? (fileName => host.readFile!(fileName)) : undefined, } : undefined }, encounteredError: false, reportedDiagnostic: false, @@ -4658,6 +4719,12 @@ namespace ts { } if (type.flags & TypeFlags.Any) { + if (type.aliasSymbol) { + return factory.createTypeReferenceNode(symbolToEntityNameNode(type.aliasSymbol), mapToTypeNodes(type.aliasTypeArguments, context)); + } + if (type === unresolvedType) { + return addSyntheticLeadingComment(factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), SyntaxKind.MultiLineCommentTrivia, "unresolved"); + } context.approximateLength += 3; return factory.createKeywordTypeNode(type === intrinsicMarkerType ? SyntaxKind.IntrinsicKeyword : SyntaxKind.AnyKeyword); } @@ -5843,6 +5910,11 @@ namespace ts { return specifier; } + function symbolToEntityNameNode(symbol: Symbol): EntityName { + const identifier = factory.createIdentifier(unescapeLeadingUnderscores(symbol.escapedName)); + return symbol.parent ? factory.createQualifiedName(symbolToEntityNameNode(symbol.parent), identifier) : identifier; + } + function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: readonly TypeNode[]): TypeNode { const chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope)); // If we're using aliases outside the current scope, dont bother with the module @@ -5852,7 +5924,7 @@ namespace ts { const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined; const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context); const specifier = getSpecifierForModuleSymbol(chain[0], context); - if (!(context.flags & NodeBuilderFlags.AllowNodeModulesRelativePaths) && getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && specifier.indexOf("/node_modules/") >= 0) { + if (!(context.flags & NodeBuilderFlags.AllowNodeModulesRelativePaths) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && specifier.indexOf("/node_modules/") >= 0) { // If ultimately we can only name the symbol with a reference that dives into a `node_modules` folder, we should error // since declaration files with these kinds of references are liable to fail when published :( context.encounteredError = true; @@ -6101,7 +6173,7 @@ namespace ts { if (nameType) { if (nameType.flags & TypeFlags.StringOrNumberLiteral) { const name = "" + (nameType as StringLiteralType | NumberLiteralType).value; - if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) { + if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && !isNumericLiteralName(name)) { return factory.createStringLiteral(name, !!singleQuote); } if (isNumericLiteralName(name) && startsWith(name, "-")) { @@ -6116,7 +6188,7 @@ namespace ts { } function createPropertyNameNodeForIdentifierOrLiteral(name: string, stringNamed?: boolean, singleQuote?: boolean) { - return isIdentifierText(name, compilerOptions.target) ? factory.createIdentifier(name) : + return isIdentifierText(name, getEmitScriptTarget(compilerOptions)) ? factory.createIdentifier(name) : !stringNamed && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : factory.createStringLiteral(name, !!singleQuote); } @@ -6162,7 +6234,7 @@ namespace ts { * so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym` */ function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) { - if (type !== errorType && enclosingDeclaration) { + if (!isErrorType(type) && enclosingDeclaration) { const declWithExistingAnnotation = getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration); if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation) && !isGetAccessorDeclaration(declWithExistingAnnotation)) { // try to reuse the existing annotation @@ -6186,7 +6258,7 @@ namespace ts { } function serializeReturnTypeForSignature(context: NodeBuilderContext, type: Type, signature: Signature, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) { - if (type !== errorType && context.enclosingDeclaration) { + if (!isErrorType(type) && context.enclosingDeclaration) { const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration); if (!!findAncestor(annotation, n => n === context.enclosingDeclaration) && annotation) { const annotated = getTypeFromTypeNode(annotation); @@ -6326,7 +6398,7 @@ namespace ts { ); } } - if (isTypeReferenceNode(node) && isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type, /*ignoreErrors*/ true))) { + if (isTypeReferenceNode(node) && isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(node, SymbolFlags.Type, /*ignoreErrors*/ true))) { return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node); } if (isLiteralImportTypeNode(node)) { @@ -6493,7 +6565,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports(map(flatMap(excessExports, e => getNamesOfDeclaration(e)), id => factory.createExportSpecifier(/*alias*/ undefined, id))), + factory.createNamedExports(map(flatMap(excessExports, e => getNamesOfDeclaration(e)), id => factory.createExportSpecifier(/*isTypeOnly*/ false, /*alias*/ undefined, id))), /*moduleSpecifier*/ undefined )]) ) @@ -6556,7 +6628,7 @@ namespace ts { function inlineExportModifiers(statements: Statement[]) { // Pass 3: Move all `export {}`'s to `export` modifiers where possible - const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && isNamedExports(d.exportClause)); + const index = findIndex(statements, d => isExportDeclaration(d) && !d.moduleSpecifier && !d.assertClause && !!d.exportClause && isNamedExports(d.exportClause)); if (index >= 0) { const exportDecl = statements[index] as ExportDeclaration & { readonly exportClause: NamedExports }; const replacements = mapDefined(exportDecl.exportClause.elements, e => { @@ -6588,7 +6660,8 @@ namespace ts { exportDecl.exportClause, replacements ), - exportDecl.moduleSpecifier + exportDecl.moduleSpecifier, + exportDecl.assertClause ); } } @@ -6750,7 +6823,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(alias, localName)]) + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, alias, localName)]) ), ModifierFlags.None ); @@ -6788,7 +6861,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(name, localName)]) + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, name, localName)]) ), ModifierFlags.None ); @@ -6848,7 +6921,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(getInternalSymbolName(symbol, symbolName), symbolName)]) + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, getInternalSymbolName(symbol, symbolName), symbolName)]) ), ModifierFlags.None); } } @@ -6987,7 +7060,7 @@ namespace ts { const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true); includePrivateSymbol(target || s); const targetName = target ? getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)) : localName; - return factory.createExportSpecifier(name === targetName ? undefined : targetName, name); + return factory.createExportSpecifier(/*isTypeOnly*/ false, name === targetName ? undefined : targetName, name); })) )]); addResult(factory.createModuleDeclaration( @@ -7093,7 +7166,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(d.expression, factory.createIdentifier(InternalSymbolName.Default))]) + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, d.expression, factory.createIdentifier(InternalSymbolName.Default))]) ) : d); const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced, removeExportModifier) : defaultReplaced; fakespace = factory.updateModuleDeclaration( @@ -7218,6 +7291,28 @@ namespace ts { ), symbol.declarations && filter(symbol.declarations, d => isClassDeclaration(d) || isClassExpression(d))[0]), modifierFlags); } + function getSomeTargetNameFromDeclarations(declarations: Declaration[] | undefined) { + return firstDefined(declarations, d => { + if (isImportSpecifier(d) || isExportSpecifier(d)) { + return idText(d.propertyName || d.name); + } + if (isBinaryExpression(d) || isExportAssignment(d)) { + const expression = isExportAssignment(d) ? d.expression : d.right; + if (isPropertyAccessExpression(expression)) { + return idText(expression.name); + } + } + if (isAliasSymbolDeclaration(d)) { + // This is... heuristic, at best. But it's probably better than always printing the name of the shorthand ambient module. + const name = getNameOfDeclaration(d); + if (name && isIdentifier(name)) { + return idText(name); + } + } + return undefined; + }); + } + function serializeAsAlias(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { // synthesize an alias, eg `export { symbolName as Name }` // need to mark the alias `symbol` points at @@ -7228,8 +7323,10 @@ namespace ts { if (!target) { return; } - let verbatimTargetName = unescapeLeadingUnderscores(target.escapedName); - if (verbatimTargetName === InternalSymbolName.ExportEquals && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) { + // If `target` refers to a shorthand module symbol, the name we're trying to pull out isn;t recoverable from the target symbol + // In such a scenario, we must fall back to looking for an alias declaration on `symbol` and pulling the target name from that + let verbatimTargetName = isShorthandAmbientModuleSymbol(target) && getSomeTargetNameFromDeclarations(symbol.declarations) || unescapeLeadingUnderscores(target.escapedName); + if (verbatimTargetName === InternalSymbolName.ExportEquals && (getESModuleInterop(compilerOptions) || compilerOptions.allowSyntheticDefaultImports)) { // target refers to an `export=` symbol that was hoisted into a synthetic default - rename here to match verbatimTargetName = InternalSymbolName.Default; } @@ -7245,10 +7342,12 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports([factory.createImportSpecifier( + /*isTypeOnly*/ false, propertyName && isIdentifier(propertyName) ? factory.createIdentifier(idText(propertyName)) : undefined, factory.createIdentifier(localName) )])), - factory.createStringLiteral(specifier) + factory.createStringLiteral(specifier), + /*importClause*/ undefined ), ModifierFlags.None); break; } @@ -7324,7 +7423,8 @@ namespace ts { // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag // In such cases, the `target` refers to the module itself already - factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) + factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), + /*assertClause*/ undefined ), ModifierFlags.None); break; case SyntaxKind.NamespaceImport: @@ -7332,7 +7432,8 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*importClause*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))), - factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)) + factory.createStringLiteral(getSpecifierForModuleSymbol(target, context)), + /*assertClause*/ undefined ), ModifierFlags.None); break; case SyntaxKind.NamespaceExport: @@ -7353,11 +7454,13 @@ namespace ts { /*importClause*/ undefined, factory.createNamedImports([ factory.createImportSpecifier( + /*isTypeOnly*/ false, localName !== verbatimTargetName ? factory.createIdentifier(verbatimTargetName) : undefined, factory.createIdentifier(localName) ) ])), - factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)) + factory.createStringLiteral(getSpecifierForModuleSymbol(target.parent || target, context)), + /*assertClause*/ undefined ), ModifierFlags.None); break; case SyntaxKind.ExportSpecifier: @@ -7398,7 +7501,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(localName !== targetName ? targetName : undefined, localName)]), + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, localName !== targetName ? targetName : undefined, localName)]), specifier ), ModifierFlags.None); } @@ -7914,7 +8017,7 @@ namespace ts { if (nameType) { if (nameType.flags & TypeFlags.StringOrNumberLiteral) { const name = "" + (nameType as StringLiteralType | NumberLiteralType).value; - if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) { + if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && !isNumericLiteralName(name)) { return `"${escapeString(name, CharacterCodes.doubleQuote)}"`; } if (isNumericLiteralName(name) && startsWith(name, "-")) { @@ -8243,6 +8346,12 @@ namespace ts { return type && (type.flags & TypeFlags.Any) !== 0; } + function isErrorType(type: Type) { + // The only 'any' types that have alias symbols are those manufactured by getTypeFromTypeAliasReference for + // a reference to an unresolved symbol. We want those to behave like the errorType. + return type === errorType || !!(type.flags & TypeFlags.Any && type.aliasSymbol); + } + // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been // assigned by contextual typing. function getTypeForBindingElementParent(node: BindingElementGrandparent) { @@ -8788,7 +8897,7 @@ namespace ts { if (!declaredType) { return type; } - else if (declaredType !== errorType && type !== errorType && !isTypeIdenticalTo(declaredType, type)) { + else if (!isErrorType(declaredType) && !isErrorType(type) && !isTypeIdenticalTo(declaredType, type)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type); } } @@ -9749,7 +9858,7 @@ namespace ts { if (!implementsTypeNodes) continue; for (const node of implementsTypeNodes) { const implementsType = getTypeFromTypeNode(node); - if (implementsType !== errorType) { + if (!isErrorType(implementsType)) { if (resolvedImplementsTypes === emptyArray) { resolvedImplementsTypes = [implementsType as ObjectType]; } @@ -9833,7 +9942,7 @@ namespace ts { baseType = getReturnTypeOfSignature(constructors[0]); } - if (baseType === errorType) { + if (isErrorType(baseType)) { return type.resolvedBaseTypes = emptyArray; } const reducedBaseType = getReducedType(baseType); @@ -9891,7 +10000,7 @@ namespace ts { if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration as InterfaceDeclaration)) { for (const node of getInterfaceBaseTypeNodes(declaration as InterfaceDeclaration)!) { const baseType = getReducedType(getTypeFromTypeNode(node)); - if (baseType !== errorType) { + if (!isErrorType(baseType)) { if (isValidBaseType(baseType)) { if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === emptyArray) { @@ -11187,6 +11296,22 @@ namespace ts { return getCheckFlags(s) & CheckFlags.Late; } + function forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(type: Type, include: TypeFlags, stringsOnly: boolean, cb: (keyType: Type) => void) { + for (const prop of getPropertiesOfType(type)) { + cb(getLiteralTypeFromProperty(prop, include)); + } + if (type.flags & TypeFlags.Any) { + cb(stringType); + } + else { + for (const info of getIndexInfosOfType(type)) { + if (!stringsOnly || info.keyType.flags & (TypeFlags.String | TypeFlags.TemplateLiteral)) { + cb(info.keyType); + } + } + } + } + /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); @@ -11204,19 +11329,7 @@ namespace ts { const include = keyofStringsOnly ? TypeFlags.StringLiteral : TypeFlags.StringOrNumberLiteralOrUnique; if (isMappedTypeWithKeyofConstraintDeclaration(type)) { // We have a { [P in keyof T]: X } - for (const prop of getPropertiesOfType(modifiersType)) { - addMemberForKeyType(getLiteralTypeFromProperty(prop, include)); - } - if (modifiersType.flags & TypeFlags.Any) { - addMemberForKeyType(stringType); - } - else { - for (const info of getIndexInfosOfType(modifiersType)) { - if (!keyofStringsOnly || info.keyType.flags & (TypeFlags.String | TypeFlags.TemplateLiteral)) { - addMemberForKeyType(info.keyType); - } - } - } + forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, include, keyofStringsOnly, addMemberForKeyType); } else { forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType); @@ -11843,7 +11956,7 @@ namespace ts { let mergedInstantiations = false; for (const current of containingType.types) { const type = getApparentType(current); - if (!(type === errorType || type.flags & TypeFlags.Never)) { + if (!(isErrorType(type) || type.flags & TypeFlags.Never)) { const prop = getPropertyOfType(type, name, skipObjectFunctionPropertyAugment); const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop) { @@ -11951,7 +12064,7 @@ namespace ts { else if (type !== firstType) { checkFlags |= CheckFlags.HasNonUniformType; } - if (isLiteralType(type)) { + if (isLiteralType(type) || isPatternLiteralType(type)) { checkFlags |= CheckFlags.HasLiteralType; } if (type.flags & TypeFlags.Never) { @@ -12790,7 +12903,7 @@ namespace ts { function isValidIndexKeyType(type: Type): boolean { return !!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol)) || isPatternLiteralType(type) || - !!(type.flags & TypeFlags.Intersection) && !isGenericIndexType(type) && !isGenericObjectType(type) && some((type as IntersectionType).types, isValidIndexKeyType); + !!(type.flags & TypeFlags.Intersection) && !isGenericType(type) && some((type as IntersectionType).types, isValidIndexKeyType); } function getConstraintDeclaration(type: TypeParameter): TypeNode | undefined { @@ -12880,7 +12993,7 @@ namespace ts { } else { let type = getTypeFromTypeNode(constraintDeclaration); - if (type.flags & TypeFlags.Any && type !== errorType) { // Allow errorType to propegate to keep downstream errors suppressed + if (type.flags & TypeFlags.Any && !isErrorType(type)) { // Allow errorType to propegate to keep downstream errors suppressed // use keyofConstraintType as the base constraint for mapped type key constraints (unknown isn;t assignable to that, but `any` was), // use unknown otherwise type = constraintDeclaration.parent.parent.kind === SyntaxKind.MappedType ? keyofConstraintType : unknownType; @@ -12894,7 +13007,7 @@ namespace ts { function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol | undefined { const tp = getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter)!; - const host = isJSDocTemplateTag(tp.parent) ? getHostSignatureFromJSDoc(tp.parent) : tp.parent; + const host = isJSDocTemplateTag(tp.parent) ? getEffectiveContainerForJSDocTemplateTag(tp.parent) : tp.parent; return host && getSymbolOfNode(host); } @@ -13070,6 +13183,18 @@ namespace ts { * declared type. Instantiations are cached using the type identities of the type arguments as the key. */ function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol): Type { + if (getCheckFlags(symbol) & CheckFlags.Unresolved) { + const typeArguments = typeArgumentsFromTypeReferenceNode(node); + const id = getAliasId(symbol, typeArguments); + let errorType = errorTypes.get(id); + if (!errorType) { + errorType = createIntrinsicType(TypeFlags.Any, "error"); + errorType.aliasSymbol = symbol; + errorType.aliasTypeArguments = typeArguments; + errorTypes.set(id, errorType); + } + return errorType; + } const type = getDeclaredTypeOfSymbol(symbol); const typeParameters = getSymbolLinks(symbol).typeParameters; if (typeParameters) { @@ -13118,12 +13243,39 @@ namespace ts { return undefined; } - function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName | undefined, meaning: SymbolFlags, ignoreErrors?: boolean) { - if (!typeReferenceName) { - return unknownSymbol; + function getSymbolPath(symbol: Symbol): string { + return symbol.parent ? `${getSymbolPath(symbol.parent)}.${symbol.escapedName}` : symbol.escapedName as string; + } + + function getUnresolvedSymbolForEntityName(name: EntityNameOrEntityNameExpression) { + const identifier = name.kind === SyntaxKind.QualifiedName ? name.right : + name.kind === SyntaxKind.PropertyAccessExpression ? name.name : + name; + const text = identifier.escapedText; + if (text) { + const parentSymbol = name.kind === SyntaxKind.QualifiedName ? getUnresolvedSymbolForEntityName(name.left) : + name.kind === SyntaxKind.PropertyAccessExpression ? getUnresolvedSymbolForEntityName(name.expression) : + undefined; + const path = parentSymbol ? `${getSymbolPath(parentSymbol)}.${text}` : text as string; + let result = unresolvedSymbols.get(path); + if (!result) { + unresolvedSymbols.set(path, result = createSymbol(SymbolFlags.TypeAlias, text, CheckFlags.Unresolved)); + result.parent = parentSymbol; + result.declaredType = unresolvedType; + } + return result; } + return unknownSymbol; + } - return resolveEntityName(typeReferenceName, meaning, ignoreErrors) || unknownSymbol; + function resolveTypeReferenceName(typeReference: TypeReferenceType, meaning: SymbolFlags, ignoreErrors?: boolean) { + const name = getTypeReferenceName(typeReference); + if (!name) { + return unknownSymbol; + } + const symbol = resolveEntityName(name, meaning, ignoreErrors); + return symbol && symbol !== unknownSymbol ? symbol : + ignoreErrors ? unknownSymbol : getUnresolvedSymbolForEntityName(name); } function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type { @@ -13149,7 +13301,7 @@ namespace ts { } else { // Resolve the type reference as a Type for the purpose of reporting errors. - resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type); + resolveTypeReferenceName(node, SymbolFlags.Type); return getTypeOfSymbol(symbol); } } @@ -13303,18 +13455,18 @@ namespace ts { if (isJSDocTypeReference(node)) { type = getIntendedTypeFromJSDocTypeReference(node); if (!type) { - symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning, /*ignoreErrors*/ true); + symbol = resolveTypeReferenceName(node, meaning, /*ignoreErrors*/ true); if (symbol === unknownSymbol) { - symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning | SymbolFlags.Value); + symbol = resolveTypeReferenceName(node, meaning | SymbolFlags.Value); } else { - resolveTypeReferenceName(getTypeReferenceName(node), meaning); // Resolve again to mark errors, if any + resolveTypeReferenceName(node, meaning); // Resolve again to mark errors, if any } type = getTypeReferenceType(node, symbol); } } if (!type) { - symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning); + symbol = resolveTypeReferenceName(node, meaning); type = getTypeReferenceType(node, symbol); } // Cache both the resolved symbol and the resolved type. The resolved symbol is needed when we check the @@ -13381,28 +13533,48 @@ namespace ts { return getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined); } + function getGlobalTypeAliasSymbol(name: __String, arity: number, reportErrors: boolean): Symbol | undefined { + const symbol = getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined); + if (symbol) { + // Resolve the declared type of the symbol. This resolves type parameters for the type + // alias so that we can check arity. + getDeclaredTypeOfSymbol(symbol); + if (length(getSymbolLinks(symbol).typeParameters) !== arity) { + const decl = symbol.declarations && find(symbol.declarations, isTypeAliasDeclaration); + error(decl, Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity); + return undefined; + } + } + return symbol; + } + function getGlobalSymbol(name: __String, meaning: SymbolFlags, diagnostic: DiagnosticMessage | undefined): Symbol | undefined { // Don't track references for global symbols anyway, so value if `isReference` is arbitrary return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false); } - function getGlobalType(name: __String, arity: 0, reportErrors: boolean): ObjectType; - function getGlobalType(name: __String, arity: number, reportErrors: boolean): GenericType; + function getGlobalType(name: __String, arity: 0, reportErrors: true): ObjectType; + function getGlobalType(name: __String, arity: 0, reportErrors: boolean): ObjectType | undefined; + function getGlobalType(name: __String, arity: number, reportErrors: true): GenericType; + function getGlobalType(name: __String, arity: number, reportErrors: boolean): GenericType | undefined; function getGlobalType(name: __String, arity: number, reportErrors: boolean): ObjectType | undefined { const symbol = getGlobalTypeSymbol(name, reportErrors); return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined; } function getGlobalTypedPropertyDescriptorType() { - return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor" as __String, /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType; + // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times + return deferredGlobalTypedPropertyDescriptorType ||= getGlobalType("TypedPropertyDescriptor" as __String, /*arity*/ 1, /*reportErrors*/ true) || emptyGenericType; } function getGlobalTemplateStringsArrayType() { - return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType; + // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times + return deferredGlobalTemplateStringsArrayType ||= getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; } function getGlobalImportMetaType() { - return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType; + // We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times + return deferredGlobalImportMetaType ||= getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType; } function getGlobalImportMetaExpressionType() { @@ -13423,72 +13595,76 @@ namespace ts { return deferredGlobalImportMetaExpressionType; } - function getGlobalESSymbolConstructorSymbol(reportErrors: boolean) { - return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors)); + function getGlobalImportCallOptionsType(reportErrors: boolean) { + return (deferredGlobalImportCallOptionsType ||= getGlobalType("ImportCallOptions" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; } - function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean) { - return deferredGlobalESSymbolConstructorTypeSymbol || (deferredGlobalESSymbolConstructorTypeSymbol = getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors)); + function getGlobalESSymbolConstructorSymbol(reportErrors: boolean): Symbol | undefined { + return deferredGlobalESSymbolConstructorSymbol ||= getGlobalValueSymbol("Symbol" as __String, reportErrors); + } + + function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean): Symbol | undefined { + return deferredGlobalESSymbolConstructorTypeSymbol ||= getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors); } function getGlobalESSymbolType(reportErrors: boolean) { - return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalESSymbolType ||= getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalPromiseType(reportErrors: boolean) { - return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalPromiseType ||= getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalPromiseLikeType(reportErrors: boolean) { - return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalPromiseLikeType ||= getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalPromiseConstructorSymbol(reportErrors: boolean): Symbol | undefined { - return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise" as __String, reportErrors)); + return deferredGlobalPromiseConstructorSymbol ||= getGlobalValueSymbol("Promise" as __String, reportErrors); } function getGlobalPromiseConstructorLikeType(reportErrors: boolean) { - return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalPromiseConstructorLikeType ||= getGlobalType("PromiseConstructorLike" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalAsyncIterableType(reportErrors: boolean) { - return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIterableType ||= getGlobalType("AsyncIterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncIteratorType(reportErrors: boolean) { - return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIteratorType ||= getGlobalType("AsyncIterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalAsyncIterableIteratorType(reportErrors: boolean) { - return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncIterableIteratorType ||= getGlobalType("AsyncIterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncGeneratorType(reportErrors: boolean) { - return deferredGlobalAsyncGeneratorType || (deferredGlobalAsyncGeneratorType = getGlobalType("AsyncGenerator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalAsyncGeneratorType ||= getGlobalType("AsyncGenerator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIterableType(reportErrors: boolean) { - return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIterableType ||= getGlobalType("Iterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIteratorType(reportErrors: boolean) { - return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorType ||= getGlobalType("Iterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIterableIteratorType(reportErrors: boolean) { - return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIterableIteratorType ||= getGlobalType("IterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalGeneratorType(reportErrors: boolean) { - return deferredGlobalGeneratorType || (deferredGlobalGeneratorType = getGlobalType("Generator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; + return (deferredGlobalGeneratorType ||= getGlobalType("Generator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType; } function getGlobalIteratorYieldResultType(reportErrors: boolean) { - return deferredGlobalIteratorYieldResultType || (deferredGlobalIteratorYieldResultType = getGlobalType("IteratorYieldResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorYieldResultType ||= getGlobalType("IteratorYieldResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIteratorReturnResultType(reportErrors: boolean) { - return deferredGlobalIteratorReturnResultType || (deferredGlobalIteratorReturnResultType = getGlobalType("IteratorReturnResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; + return (deferredGlobalIteratorReturnResultType ||= getGlobalType("IteratorReturnResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalTypeOrUndefined(name: __String, arity = 0): ObjectType | undefined { @@ -13496,16 +13672,26 @@ namespace ts { return symbol && getTypeOfGlobalSymbol(symbol, arity) as GenericType; } - function getGlobalExtractSymbol(): Symbol { - return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)!); // TODO: GH#18217 + function getGlobalExtractSymbol(): Symbol | undefined { + // We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times + deferredGlobalExtractSymbol ||= getGlobalTypeAliasSymbol("Extract" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; + return deferredGlobalExtractSymbol === unknownSymbol ? undefined : deferredGlobalExtractSymbol; } - function getGlobalOmitSymbol(): Symbol { - return deferredGlobalOmitSymbol || (deferredGlobalOmitSymbol = getGlobalSymbol("Omit" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)!); // TODO: GH#18217 + function getGlobalOmitSymbol(): Symbol | undefined { + // We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times + deferredGlobalOmitSymbol ||= getGlobalTypeAliasSymbol("Omit" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; + return deferredGlobalOmitSymbol === unknownSymbol ? undefined : deferredGlobalOmitSymbol; + } + + function getGlobalAwaitedSymbol(reportErrors: boolean): Symbol | undefined { + // Only cache `unknownSymbol` if we are reporting errors so that we don't report the error more than once. + deferredGlobalAwaitedSymbol ||= getGlobalTypeAliasSymbol("Awaited" as __String, /*arity*/ 1, reportErrors) || (reportErrors ? unknownSymbol : undefined); + return deferredGlobalAwaitedSymbol === unknownSymbol ? undefined : deferredGlobalAwaitedSymbol; } function getGlobalBigIntType(reportErrors: boolean) { - return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; + return (deferredGlobalBigIntType ||= getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType; } /** @@ -13594,7 +13780,7 @@ namespace ts { function mayResolveTypeAlias(node: Node): boolean { switch (node.kind) { case SyntaxKind.TypeReference: - return isJSDocTypeReference(node) || !!(resolveTypeReferenceName((node as TypeReferenceNode).typeName, SymbolFlags.Type).flags & SymbolFlags.TypeAlias); + return isJSDocTypeReference(node) || !!(resolveTypeReferenceName(node as TypeReferenceNode, SymbolFlags.Type).flags & SymbolFlags.TypeAlias); case SyntaxKind.TypeQuery: return true; case SyntaxKind.TypeOperator: @@ -13879,7 +14065,6 @@ namespace ts { // We ignore 'never' types in unions if (!(flags & TypeFlags.Never)) { includes |= flags & TypeFlags.IncludesMask; - if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable; if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; if (!strictNullChecks && flags & TypeFlags.Nullable) { if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType; @@ -14039,7 +14224,9 @@ namespace ts { const includes = addTypesToUnion(typeSet, 0, types); if (unionReduction !== UnionReduction.None) { if (includes & TypeFlags.AnyOrUnknown) { - return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType; + return includes & TypeFlags.Any ? + includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : + includes & TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType; } if (exactOptionalPropertyTypes && includes & TypeFlags.Undefined) { const missingIndex = binarySearch(typeSet, missingType, getTypeId, compareValues); @@ -14184,13 +14371,19 @@ namespace ts { if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; } - else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !typeSet.has(type.id.toString())) { - if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) { - // We have seen two distinct unit types which means we should reduce to an - // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen. - includes |= TypeFlags.NonPrimitive; + else if (strictNullChecks || !(flags & TypeFlags.Nullable)) { + if (exactOptionalPropertyTypes && type === missingType) { + includes |= TypeFlags.IncludesMissingType; + type = undefinedType; + } + if (!typeSet.has(type.id.toString())) { + if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) { + // We have seen two distinct unit types which means we should reduce to an + // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen. + includes |= TypeFlags.NonPrimitive; + } + typeSet.set(type.id.toString(), type); } - typeSet.set(type.id.toString(), type); } includes |= flags & TypeFlags.IncludesMask; } @@ -14265,14 +14458,14 @@ namespace ts { return false; } - function extractIrreducible(types: Type[], flag: TypeFlags) { - if (every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag)))) { - for (let i = 0; i < types.length; i++) { - types[i] = filterType(types[i], t => !(t.flags & flag)); - } - return true; + function eachIsUnionContaining(types: Type[], flag: TypeFlags) { + return every(types, t => !!(t.flags & TypeFlags.Union) && some((t as UnionType).types, tt => !!(tt.flags & flag))); + } + + function removeFromEach(types: Type[], flag: TypeFlags) { + for (let i = 0; i < types.length; i++) { + types[i] = filterType(types[i], t => !(t.flags & flag)); } - return false; } // If the given list of types contains more than one union of primitive types, replace the @@ -14382,6 +14575,9 @@ namespace ts { if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) { orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType)); } + if (includes & TypeFlags.IncludesMissingType) { + typeSet[typeSet.indexOf(undefinedType)] = missingType; + } if (typeSet.length === 0) { return unknownType; } @@ -14398,10 +14594,13 @@ namespace ts { // reduced we'll never reduce again, so this occurs at most once. result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } - else if (extractIrreducible(typeSet, TypeFlags.Undefined)) { - result = getUnionType([getIntersectionType(typeSet), undefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); + else if (eachIsUnionContaining(typeSet, TypeFlags.Undefined)) { + const undefinedOrMissingType = exactOptionalPropertyTypes && some(typeSet, t => containsType((t as UnionType).types, missingType)) ? missingType : undefinedType; + removeFromEach(typeSet, TypeFlags.Undefined); + result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } - else if (extractIrreducible(typeSet, TypeFlags.Null)) { + else if (eachIsUnionContaining(typeSet, TypeFlags.Null)) { + removeFromEach(typeSet, TypeFlags.Null); result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } else { @@ -14489,19 +14688,58 @@ namespace ts { type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false)); } - function instantiateTypeAsMappedNameType(nameType: Type, type: MappedType, t: Type) { - return instantiateType(nameType, appendTypeMapping(type.mapper, getTypeParameterFromMappedType(type), t)); - } + /** + * This roughly mirrors `resolveMappedTypeMembers` in the nongeneric case, except only reports a union of the keys calculated, + * rather than manufacturing the properties. We can't just fetch the `constraintType` since that would ignore mappings + * and mapping the `constraintType` directly ignores how mapped types map _properties_ and not keys (thus ignoring subtype + * reduction in the constraintType) when possible. + * @param noIndexSignatures Indicates if _string_ index signatures should be elided. (other index signatures are always reported) + */ + function getIndexTypeForMappedType(type: MappedType, stringsOnly: boolean, noIndexSignatures: boolean | undefined) { + const typeParameter = getTypeParameterFromMappedType(type); + const constraintType = getConstraintTypeFromMappedType(type); + const nameType = getNameTypeFromMappedType(type.target as MappedType || type); + if (!nameType && !noIndexSignatures) { + // no mapping and no filtering required, just quickly bail to returning the constraint in the common case + return constraintType; + } + const keyTypes: Type[] = []; + if (isMappedTypeWithKeyofConstraintDeclaration(type)) { + // We have a { [P in keyof T]: X } - function getIndexTypeForMappedType(type: MappedType, noIndexSignatures: boolean | undefined) { - const constraint = filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))); - const nameType = type.declaration.nameType && getTypeFromTypeNode(type.declaration.nameType); - // If the constraint is exclusively string/number/never type(s), we need to pull the property names from the modified type and run them through the `nameType` mapper as well - // since they won't appear in the constraint, due to subtype reducing with the string/number index types - const properties = nameType && everyType(constraint, t => !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.Never))) && getPropertiesOfType(getApparentType(getModifiersTypeFromMappedType(type))); - return nameType ? - getUnionType([mapType(constraint, t => instantiateTypeAsMappedNameType(nameType, type, t)), mapType(getUnionType(map(properties || emptyArray, p => getLiteralTypeFromProperty(p, TypeFlags.StringOrNumberLiteralOrUnique))), t => instantiateTypeAsMappedNameType(nameType, type, t))]): - constraint; + // `getApparentType` on the T in a generic mapped type can trigger a circularity + // (conditionals and `infer` types create a circular dependency in the constraint resolution) + // so we only eagerly manifest the keys if the constraint is nongeneric + if (!isGenericIndexType(constraintType)) { + const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' + forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(modifiersType, TypeFlags.StringOrNumberLiteralOrUnique, stringsOnly, addMemberForKeyType); + } + else { + // we have a generic index and a homomorphic mapping (but a distributive key remapping) - we need to defer the whole `keyof whatever` for later + // since it's not safe to resolve the shape of modifier type + return getIndexTypeForGenericType(type, stringsOnly); + } + } + else { + forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType); + } + if (isGenericIndexType(constraintType)) { // include the generic component in the resulting type + forEachType(constraintType, addMemberForKeyType); + } + // we had to pick apart the constraintType to potentially map/filter it - compare the final resulting list with the original constraintType, + // so we can return the union that preserves aliases/origin data if possible + const result = noIndexSignatures ? filterType(getUnionType(keyTypes), t => !(t.flags & (TypeFlags.Any | TypeFlags.String))) : getUnionType(keyTypes); + if (result.flags & TypeFlags.Union && constraintType.flags & TypeFlags.Union && getTypeListId((result as UnionType).types) === getTypeListId((constraintType as UnionType).types)){ + return constraintType; + } + return result; + + function addMemberForKeyType(keyType: Type) { + const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType; + // `keyof` currently always returns `string | number` for concrete `string` index signatures - the below ternary keeps that behavior for mapped types + // See `getLiteralTypeFromProperties` where there's a similar ternary to cause the same behavior. + keyTypes.push(propNameType === stringType ? stringOrNumberType : propNameType); + } } // Ordinarily we reduce a keyof M, where M is a mapped type { [P in K as N

]: X }, to simply N. This however presumes @@ -14546,10 +14784,14 @@ namespace ts { return neverType; } + function isKeyTypeIncluded(keyType: Type, include: TypeFlags): boolean { + return !!(keyType.flags & include || keyType.flags & TypeFlags.Intersection && some((keyType as IntersectionType).types, t => isKeyTypeIncluded(t, include))); + } + function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeOrigin: boolean) { const origin = includeOrigin && (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); - const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && info.keyType.flags & include ? + const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && isKeyTypeIncluded(info.keyType, include) ? info.keyType === stringType && include & TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); return getUnionType(concatenate(propertyTypes, indexKeyTypes), UnionReduction.Literal, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, origin); @@ -14560,7 +14802,7 @@ namespace ts { return type.flags & TypeFlags.Union ? getIntersectionType(map((type as UnionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type as IntersectionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) || isGenericMappedType(type) && !hasDistributiveNameType(type) ? getIndexTypeForGenericType(type as InstantiableType | UnionOrIntersectionType, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? getIndexTypeForMappedType(type as MappedType, noIndexSignatures) : + getObjectFlags(type) & ObjectFlags.Mapped ? getIndexTypeForMappedType(type as MappedType, stringsOnly, noIndexSignatures) : type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : @@ -15262,10 +15504,18 @@ namespace ts { function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { let result; let extraTypes: Type[] | undefined; + let tailCount = 0; // We loop here for an immediately nested conditional type in the false position, effectively treating // types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for - // purposes of resolution. This means such types aren't subject to the instantiation depth limiter. + // purposes of resolution. We also loop here when resolution of a conditional type ends in resolution of + // another (or, through recursion, possibly the same) conditional type. In the potentially tail-recursive + // cases we increment the tail recursion counter and stop after 1000 iterations. while (true) { + if (tailCount === 1000) { + error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite); + result = errorType; + break; + } const isUnwrapped = isTypicalNondistributiveConditional(root); const checkType = instantiateType(unwrapNondistributiveConditionalTuple(root, getActualTypeVariable(root.checkType)), mapper); const checkTypeInstantiable = isGenericType(checkType); @@ -15309,6 +15559,9 @@ namespace ts { root = newRoot; continue; } + if (canTailRecurse(falseType, mapper)) { + continue; + } } result = instantiateType(falseType, mapper); break; @@ -15319,7 +15572,12 @@ namespace ts { // type Foo = T extends { x: string } ? string : number // doesn't immediately resolve to 'string' instead of being deferred. if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) { - result = instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper); + const trueType = getTypeFromTypeNode(root.node.trueType); + const trueMapper = combinedMapper || mapper; + if (canTailRecurse(trueType, trueMapper)) { + continue; + } + result = instantiateType(trueType, trueMapper); break; } } @@ -15335,6 +15593,32 @@ namespace ts { break; } return extraTypes ? getUnionType(append(extraTypes, result)) : result; + // We tail-recurse for generic conditional types that (a) have not already been evaluated and cached, and + // (b) are non distributive, have a check type that is unaffected by instantiation, or have a non-union check + // type. Note that recursion is possible only through aliased conditional types, so we only increment the tail + // recursion counter for those. + function canTailRecurse(newType: Type, newMapper: TypeMapper | undefined) { + if (newType.flags & TypeFlags.Conditional && newMapper) { + const newRoot = (newType as ConditionalType).root; + if (newRoot.outerTypeParameters) { + const typeParamMapper = combineTypeMappers((newType as ConditionalType).mapper, newMapper); + const typeArguments = map(newRoot.outerTypeParameters, t => getMappedType(t, typeParamMapper)); + const newRootMapper = createTypeMapper(newRoot.outerTypeParameters, typeArguments); + const newCheckType = newRoot.isDistributive ? getMappedType(newRoot.checkType, newRootMapper) : undefined; + if (!newCheckType || newCheckType === newRoot.checkType || !(newCheckType.flags & (TypeFlags.Union | TypeFlags.Never))) { + root = newRoot; + mapper = newRootMapper; + aliasSymbol = undefined; + aliasTypeArguments = undefined; + if (newRoot.aliasSymbol) { + tailCount++; + } + return true; + } + } + } + return false; + } } function getTrueTypeFromConditionalType(type: ConditionalType) { @@ -16230,7 +16514,7 @@ namespace ts { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { return mapTypeWithAlias(getReducedType(mappedTypeVariable), t => { - if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) { + if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) { if (!type.declaration.nameType) { if (isArrayType(t)) { return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); @@ -16275,7 +16559,7 @@ namespace ts { function instantiateMappedArrayType(arrayType: Type, mappedType: MappedType, mapper: TypeMapper) { const elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper); - return elementType === errorType ? errorType : + return isErrorType(elementType) ? errorType : createArrayType(elementType, getModifiedReadonlyState(isReadonlyArrayType(arrayType), getMappedTypeModifiers(mappedType))); } @@ -16355,8 +16639,8 @@ namespace ts { if (!couldContainTypeVariables(type)) { return type; } - if (instantiationDepth === 500 || instantiationCount >= 5000000) { - // We have reached 500 recursive type instantiations, or 5M type instantiations caused by the same statement + if (instantiationDepth === 100 || instantiationCount >= 5000000) { + // We have reached 100 recursive type instantiations, or 5M type instantiations caused by the same statement // or expression. There is a very high likelyhood we're dealing with a combination of infinite generic types // that perpetually generate new type identities, so we stop the recursion here by yielding the error type. tracing?.instant(tracing.Phase.CheckTypes, "instantiateType_DepthLimit", { typeId: type.id, instantiationDepth, instantiationCount }); @@ -17487,7 +17771,8 @@ namespace ts { let sourceStack: Type[]; let targetStack: Type[]; let maybeCount = 0; - let depth = 0; + let sourceDepth = 0; + let targetDepth = 0; let expandingFlags = ExpandingFlags.None; let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid @@ -17497,12 +17782,12 @@ namespace ts { Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); - const result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage); + const result = isRelatedTo(source, target, RecursionFlags.Both, /*reportErrors*/ !!errorNode, headMessage); if (incompatibleStack.length) { reportIncompatibleStack(); } if (overflow) { - tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth }); + tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth: sourceDepth, targetDepth }); const diag = error(errorNode || currentNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); if (errorOutputContainer) { (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag); @@ -17603,7 +17888,7 @@ namespace ts { path = `${str}`; } // Otherwise write a dotted name if possible - else if (isIdentifierText(str, compilerOptions.target)) { + else if (isIdentifierText(str, getEmitScriptTarget(compilerOptions))) { path = `${path}.${str}`; } // Failing that, check if the name is already a computed name @@ -17741,6 +18026,13 @@ namespace ts { message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; } else { + if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.Union) { + const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as StringLiteralType, target as UnionType); + if (suggestedType) { + reportError(Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType)); + return; + } + } message = Diagnostics.Type_0_is_not_assignable_to_type_1; } } @@ -17800,13 +18092,17 @@ namespace ts { return true; } + function isRelatedToWorker(source: Type, target: Type, reportErrors: boolean) { + return isRelatedTo(source, target, RecursionFlags.Both, reportErrors); + } + /** * Compare two types and return * * Ternary.True if they are related with no assumptions, * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ - function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { @@ -17827,7 +18123,7 @@ namespace ts { if (source === target) return Ternary.True; if (relation === identityRelation) { - return isIdenticalTo(source, target); + return isIdenticalTo(source, target, recursionFlags); } // We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common, @@ -17881,8 +18177,8 @@ namespace ts { const targetString = typeToString(originalTarget.aliasSymbol ? originalTarget : target); const calls = getSignaturesOfType(source, SignatureKind.Call); const constructs = getSignaturesOfType(source, SignatureKind.Construct); - if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) || - constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) { + if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, RecursionFlags.Source, /*reportErrors*/ false) || + constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, RecursionFlags.Source, /*reportErrors*/ false)) { reportError(Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString); } else { @@ -17902,11 +18198,11 @@ namespace ts { // and we need to handle "each" relations before "some" relations for the same kind of type. if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) { result = getConstituentCount(source) * getConstituentCount(target) >= 4 ? - recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck) : + recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags) : structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck); } if (!result && !(source.flags & TypeFlags.Union) && (source.flags & (TypeFlags.StructuredOrInstantiable) || target.flags & TypeFlags.StructuredOrInstantiable)) { - if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) { + if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags)) { resetErrorInfo(saveErrorInfo); } } @@ -17928,7 +18224,7 @@ namespace ts { if (constraint && (source.flags & TypeFlags.Intersection || target.flags & TypeFlags.Union)) { if (everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this - if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); } } @@ -17954,7 +18250,7 @@ namespace ts { target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) || isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) { inPropertyCheck = true; - result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck); + result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags); inPropertyCheck = false; } @@ -17988,7 +18284,7 @@ namespace ts { const targetTypes = (target as IntersectionType).types; const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode); const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode); - if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType && + if (!isErrorType(intrinsicAttributes) && !isErrorType(intrinsicClassAttributes) && (contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) { // do not report top error return result; @@ -18036,7 +18332,7 @@ namespace ts { } } - function isIdenticalTo(source: Type, target: Type): Ternary { + function isIdenticalTo(source: Type, target: Type, recursionFlags: RecursionFlags): Ternary { if (source.flags !== target.flags) return Ternary.False; if (source.flags & TypeFlags.Singleton) return Ternary.True; traceUnionsOrIntersectionsTooLarge(source, target); @@ -18047,7 +18343,7 @@ namespace ts { } return result; } - return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, IntersectionState.None); + return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, IntersectionState.None, recursionFlags); } function getTypeOfPropertyInTypes(types: Type[], name: __String) { @@ -18131,7 +18427,7 @@ namespace ts { } return true; } - if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), reportErrors)) { + if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), RecursionFlags.Both, reportErrors)) { if (reportErrors) { reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop)); } @@ -18167,21 +18463,21 @@ namespace ts { } const match = getMatchingUnionConstituentForType(target as UnionType, source); if (match) { - const related = isRelatedTo(source, match, /*reportErrors*/ false); + const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false); if (related) { return related; } } } for (const type of targetTypes) { - const related = isRelatedTo(source, type, /*reportErrors*/ false); + const related = isRelatedTo(source, type, RecursionFlags.Target, /*reportErrors*/ false); if (related) { return related; } } if (reportErrors) { const bestMatchingType = getBestMatchingType(source, target, isRelatedTo); - isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); + isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], RecursionFlags.Target, /*reportErrors*/ true); } return Ternary.False; } @@ -18190,7 +18486,7 @@ namespace ts { let result = Ternary.True; const targetTypes = target.types; for (const targetType of targetTypes) { - const related = isRelatedTo(source, targetType, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(source, targetType, RecursionFlags.Target, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { return Ternary.False; } @@ -18206,7 +18502,7 @@ namespace ts { } const len = sourceTypes.length; for (let i = 0; i < len; i++) { - const related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceTypes[i], target, RecursionFlags.Source, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState); if (related) { return related; } @@ -18238,13 +18534,13 @@ namespace ts { // union has a union of objects intersected with it. In such cases, if the input was, eg `("a" | "b" | "c") & (string | boolean | {} | {whatever})`, // the result will have the structure `"a" | "b" | "c" | "a" & {} | "b" & {} | "c" & {} | "a" & {whatever} | "b" & {whatever} | "c" & {whatever}` // - the resulting union has a length which is a multiple of the original union, and the elements correspond modulo the length of the original union - const related = isRelatedTo(sourceType, (undefinedStrippedTarget as UnionType).types[i % (undefinedStrippedTarget as UnionType).types.length], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, (undefinedStrippedTarget as UnionType).types[i % (undefinedStrippedTarget as UnionType).types.length], RecursionFlags.Both, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (related) { result &= related; continue; } } - const related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, target, RecursionFlags.Source, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { return Ternary.False; } @@ -18274,31 +18570,31 @@ namespace ts { // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_. // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be) - related = relation === identityRelation ? isRelatedTo(s, t, /*reportErrors*/ false) : compareTypesIdentical(s, t); + related = relation === identityRelation ? isRelatedTo(s, t, RecursionFlags.Both, /*reportErrors*/ false) : compareTypesIdentical(s, t); } else if (variance === VarianceFlags.Covariant) { - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } else if (variance === VarianceFlags.Contravariant) { - related = isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(t, s, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } else if (variance === VarianceFlags.Bivariant) { // In the bivariant case we first compare contravariantly without reporting // errors. Then, if that doesn't succeed, we compare covariantly with error // reporting. Thus, error elaboration will be based on the the covariant check, // which is generally easier to reason about. - related = isRelatedTo(t, s, /*reportErrors*/ false); + related = isRelatedTo(t, s, RecursionFlags.Both, /*reportErrors*/ false); if (!related) { - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } } else { // In the invariant case we first compare covariantly, and only when that // succeeds do we proceed to compare contravariantly. Thus, error elaboration // will typically be based on the covariant check. - related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState); + related = isRelatedTo(s, t, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (related) { - related &= isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState); + related &= isRelatedTo(t, s, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } } if (!related) { @@ -18315,7 +18611,7 @@ namespace ts { // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion // and issue an error. Otherwise, actually compare the structure of the two types. - function recursiveTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function recursiveTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, recursionFlags: RecursionFlags): Ternary { if (overflow) { return Ternary.False; } @@ -18359,7 +18655,7 @@ namespace ts { return Ternary.Maybe; } } - if (depth === 100) { + if (sourceDepth === 100 || targetDepth === 100) { overflow = true; return Ternary.False; } @@ -18367,12 +18663,17 @@ namespace ts { const maybeStart = maybeCount; maybeKeys[maybeCount] = id; maybeCount++; - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; + if (recursionFlags & RecursionFlags.Source) { + sourceStack[sourceDepth] = source; + sourceDepth++; + } + if (recursionFlags & RecursionFlags.Target) { + targetStack[targetDepth] = target; + targetDepth++; + } const saveExpandingFlags = expandingFlags; - if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= ExpandingFlags.Source; - if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= ExpandingFlags.Target; + if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source; + if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target; let originalHandler: typeof outofbandVarianceMarkerHandler; let propagatingVarianceFlags: RelationComparisonResult = 0; if (outofbandVarianceMarkerHandler) { @@ -18389,7 +18690,8 @@ namespace ts { sourceIdStack: sourceStack.map(t => t.id), targetId: target.id, targetIdStack: targetStack.map(t => t.id), - depth, + depth: sourceDepth, + targetDepth }); } @@ -18398,9 +18700,14 @@ namespace ts { outofbandVarianceMarkerHandler = originalHandler; } expandingFlags = saveExpandingFlags; - depth--; + if (recursionFlags & RecursionFlags.Source) { + sourceDepth--; + } + if (recursionFlags & RecursionFlags.Target) { + targetDepth--; + } if (result) { - if (result === Ternary.True || depth === 0) { + if (result === Ternary.True || (sourceDepth === 0 && targetDepth === 0)) { if (result === Ternary.True || result === Ternary.Maybe) { // If result is definitely true, record all maybe keys as having succeeded. Also, record Ternary.Maybe // results as having succeeded once we reach depth 0, but never record Ternary.Unknown results. @@ -18456,7 +18763,7 @@ namespace ts { if (constraints !== (source as IntersectionType).types) { source = getIntersectionType(constraints); if (!(source.flags & TypeFlags.Intersection)) { - return isRelatedTo(source, target, /*reportErrors*/ false); + return isRelatedTo(source, target, RecursionFlags.Source, /*reportErrors*/ false); } } } @@ -18478,22 +18785,22 @@ namespace ts { const flags = source.flags & target.flags; if (relation === identityRelation && !(flags & TypeFlags.Object)) { if (flags & TypeFlags.Index) { - return isRelatedTo((source as IndexType).type, (target as IndexType).type, /*reportErrors*/ false); + return isRelatedTo((source as IndexType).type, (target as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false); } let result = Ternary.False; if (flags & TypeFlags.IndexedAccess) { - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, /*reportErrors*/ false)) { + if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } } if (flags & TypeFlags.Conditional) { if ((source as ConditionalType).root.isDistributive === (target as ConditionalType).root.isDistributive) { - if (result = isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source as ConditionalType).extendsType, (target as ConditionalType).extendsType, /*reportErrors*/ false)) { - if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target as ConditionalType), /*reportErrors*/ false)) { - if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), /*reportErrors*/ false)) { + if (result = isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source as ConditionalType).extendsType, (target as ConditionalType).extendsType, RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getTrueTypeFromConditionalType(source as ConditionalType), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } @@ -18502,7 +18809,7 @@ namespace ts { } } if (flags & TypeFlags.Substitution) { - return isRelatedTo((source as SubstitutionType).substitute, (target as SubstitutionType).substitute, /*reportErrors*/ false); + return isRelatedTo((source as SubstitutionType).substitute, (target as SubstitutionType).substitute, RecursionFlags.Both, /*reportErrors*/ false); } return Ternary.False; } @@ -18530,19 +18837,19 @@ namespace ts { // For a generic type T and a type U that is assignable to T, [...U] is assignable to T, U is assignable to readonly [...T], // and U is assignable to [...T] when U is constrained to a mutable array or tuple type. - if (isSingleElementGenericTupleType(source) && !source.target.readonly && (result = isRelatedTo(getTypeArguments(source)[0], target)) || - isSingleElementGenericTupleType(target) && (target.target.readonly || isMutableArrayOrTuple(getBaseConstraintOfType(source) || source)) && (result = isRelatedTo(source, getTypeArguments(target)[0]))) { + if (isSingleElementGenericTupleType(source) && !source.target.readonly && (result = isRelatedTo(getTypeArguments(source)[0], target, RecursionFlags.Source)) || + isSingleElementGenericTupleType(target) && (target.target.readonly || isMutableArrayOrTuple(getBaseConstraintOfType(source) || source)) && (result = isRelatedTo(source, getTypeArguments(target)[0], RecursionFlags.Target))) { return result; } if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. - if (getObjectFlags(source) & ObjectFlags.Mapped && !(source as MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as MappedType))) { + if (getObjectFlags(source) & ObjectFlags.Mapped && !(source as MappedType).declaration.nameType && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source as MappedType), RecursionFlags.Both)) { if (!(getMappedTypeModifiers(source as MappedType) & MappedTypeModifiers.IncludeOptional)) { const templateType = getTemplateTypeFromMappedType(source as MappedType); const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source as MappedType)); - if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) { + if (result = isRelatedTo(templateType, indexedAccessType, RecursionFlags.Both, reportErrors)) { return result; } } @@ -18552,14 +18859,14 @@ namespace ts { const targetType = (target as IndexType).type; // A keyof S is related to a keyof T if T is related to S. if (source.flags & TypeFlags.Index) { - if (result = isRelatedTo(targetType, (source as IndexType).type, /*reportErrors*/ false)) { + if (result = isRelatedTo(targetType, (source as IndexType).type, RecursionFlags.Both, /*reportErrors*/ false)) { return result; } } if (isTupleType(targetType)) { // An index type can have a tuple type target when the tuple type contains variadic elements. // Check if the source is related to the known keys of the tuple type. - if (result = isRelatedTo(source, getKnownKeysOfTupleType(targetType), reportErrors)) { + if (result = isRelatedTo(source, getKnownKeysOfTupleType(targetType), RecursionFlags.Target, reportErrors)) { return result; } } @@ -18572,7 +18879,36 @@ namespace ts { // false positives. For example, given 'T extends { [K in keyof T]: string }', // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when // related to other types. - if (isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors) === Ternary.True) { + if (isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), RecursionFlags.Target, reportErrors) === Ternary.True) { + return Ternary.True; + } + } + else if (isGenericMappedType(targetType)) { + // generic mapped types that don't simplify or have a constraint still have a very simple set of keys we can compare against + // - their nameType or constraintType. + // In many ways, this comparison is a deferred version of what `getIndexTypeForMappedType` does to actually resolve the keys for _non_-generic types + + const nameType = getNameTypeFromMappedType(targetType); + const constraintType = getConstraintTypeFromMappedType(targetType); + let targetKeys; + if (nameType && isMappedTypeWithKeyofConstraintDeclaration(targetType)) { + // we need to get the apparent mappings and union them with the generic mappings, since some properties may be + // missing from the `constraintType` which will otherwise be mapped in the object + const modifiersType = getApparentType(getModifiersTypeFromMappedType(targetType)); + const mappedKeys: Type[] = []; + forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType( + modifiersType, + TypeFlags.StringOrNumberLiteralOrUnique, + /*stringsOnly*/ false, + t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(targetType.mapper, getTypeParameterFromMappedType(targetType), t))) + ); + // We still need to include the non-apparent (and thus still generic) keys in the target side of the comparison (in case they're in the source side) + targetKeys = getUnionType([...mappedKeys, nameType]); + } + else { + targetKeys = nameType || constraintType; + } + if (isRelatedTo(source, targetKeys, RecursionFlags.Target, reportErrors) === Ternary.True) { return Ternary.True; } } @@ -18582,8 +18918,8 @@ namespace ts { if (source.flags & TypeFlags.IndexedAccess) { // Relate components directly before falling back to constraint relationships // A type S[K] is related to a type T[J] if S is related to T and K is related to J. - if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, reportErrors)) { - result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, reportErrors); + if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors); } if (result) { resetErrorInfo(saveErrorInfo); @@ -18608,7 +18944,7 @@ namespace ts { // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, reportErrors)) { + if (result = isRelatedTo(source, constraint, RecursionFlags.Target, reportErrors)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -18622,40 +18958,62 @@ namespace ts { originalErrorInfo = undefined; } } - else if (isGenericMappedType(target) && !target.declaration.nameType) { - // A source type T is related to a target type { [P in X]: T[P] } - const template = getTemplateTypeFromMappedType(target); + else if (isGenericMappedType(target)) { + // Check if source type `S` is related to target type `{ [P in Q]: T }` or `{ [P in Q as R]: T}`. + const keysRemapped = !!target.declaration.nameType; + const templateType = getTemplateTypeFromMappedType(target); const modifiers = getMappedTypeModifiers(target); if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) { - if (template.flags & TypeFlags.IndexedAccess && (template as IndexedAccessType).objectType === source && - (template as IndexedAccessType).indexType === getTypeParameterFromMappedType(target)) { + // If the mapped type has shape `{ [P in Q]: T[P] }`, + // source `S` is related to target if `T` = `S`, i.e. `S` is related to `{ [P in Q]: S[P] }`. + if (!keysRemapped && templateType.flags & TypeFlags.IndexedAccess && (templateType as IndexedAccessType).objectType === source && + (templateType as IndexedAccessType).indexType === getTypeParameterFromMappedType(target)) { return Ternary.True; } if (!isGenericMappedType(source)) { - const targetConstraint = getConstraintTypeFromMappedType(target); + // If target has shape `{ [P in Q as R]: T}`, then its keys have type `R`. + // If target has shape `{ [P in Q]: T }`, then its keys have type `Q`. + const targetKeys = keysRemapped ? getNameTypeFromMappedType(target)! : getConstraintTypeFromMappedType(target); + // Type of the keys of source type `S`, i.e. `keyof S`. const sourceKeys = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true); const includeOptional = modifiers & MappedTypeModifiers.IncludeOptional; - const filteredByApplicability = includeOptional ? intersectTypes(targetConstraint, sourceKeys) : undefined; - // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X. - // A source type T is related to a target type { [P in Q]?: X } if some constituent Q' of Q is related to keyof T and T[Q'] is related to X. + const filteredByApplicability = includeOptional ? intersectTypes(targetKeys, sourceKeys) : undefined; + // A source type `S` is related to a target type `{ [P in Q]: T }` if `Q` is related to `keyof S` and `S[Q]` is related to `T`. + // A source type `S` is related to a target type `{ [P in Q as R]: T }` if `R` is related to `keyof S` and `S[R]` is related to `T. + // A source type `S` is related to a target type `{ [P in Q]?: T }` if some constituent `Q'` of `Q` is related to `keyof S` and `S[Q']` is related to `T`. + // A source type `S` is related to a target type `{ [P in Q as R]?: T }` if some constituent `R'` of `R` is related to `keyof S` and `S[R']` is related to `T`. if (includeOptional ? !(filteredByApplicability!.flags & TypeFlags.Never) - : isRelatedTo(targetConstraint, sourceKeys)) { + : isRelatedTo(targetKeys, sourceKeys, RecursionFlags.Both)) { const templateType = getTemplateTypeFromMappedType(target); const typeParameter = getTypeParameterFromMappedType(target); - // Fastpath: When the template has the form Obj[P] where P is the mapped type parameter, directly compare `source` with `Obj` - // to avoid creating the (potentially very large) number of new intermediate types made by manufacturing `source[P]` + // Fastpath: When the template type has the form `Obj[P]` where `P` is the mapped type parameter, directly compare source `S` with `Obj` + // to avoid creating the (potentially very large) number of new intermediate types made by manufacturing `S[P]`. const nonNullComponent = extractTypesOfKind(templateType, ~TypeFlags.Nullable); - if (nonNullComponent.flags & TypeFlags.IndexedAccess && (nonNullComponent as IndexedAccessType).indexType === typeParameter) { - if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, reportErrors)) { + if (!keysRemapped && nonNullComponent.flags & TypeFlags.IndexedAccess && (nonNullComponent as IndexedAccessType).indexType === typeParameter) { + if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, RecursionFlags.Target, reportErrors)) { return result; } } else { - const indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter; + // We need to compare the type of a property on the source type `S` to the type of the same property on the target type, + // so we need to construct an indexing type representing a property, and then use indexing type to index the source type for comparison. + + // If the target type has shape `{ [P in Q]: T }`, then a property of the target has type `P`. + // If the target type has shape `{ [P in Q]?: T }`, then a property of the target has type `P`, + // but the property is optional, so we only want to compare properties `P` that are common between `keyof S` and `Q`. + // If the target type has shape `{ [P in Q as R]: T }`, then a property of the target has type `R`. + // If the target type has shape `{ [P in Q as R]?: T }`, then a property of the target has type `R`, + // but the property is optional, so we only want to compare properties `R` that are common between `keyof S` and `R`. + const indexingType = keysRemapped + ? (filteredByApplicability || targetKeys) + : filteredByApplicability + ? getIntersectionType([filteredByApplicability, typeParameter]) + : typeParameter; const indexedAccessType = getIndexedAccessType(source, indexingType); - if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { + // Compare `S[indexingType]` to `T`, where `T` is the type of a property of the target type. + if (result = isRelatedTo(indexedAccessType, templateType, RecursionFlags.Both, reportErrors)) { return result; } } @@ -18684,10 +19042,11 @@ namespace ts { } // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - let localResult: Ternary | undefined; - if (skipTrue || (localResult = isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.trueType), distributionMapper) : getTrueTypeFromConditionalType(c), /*reportErrors*/ false))) { - if (!skipFalse) { - localResult = (localResult || Ternary.Maybe) & isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.falseType), distributionMapper) : getFalseTypeFromConditionalType(c), /*reportErrors*/ false); + const expanding = isDeeplyNestedType(target, targetStack, targetDepth); + let localResult: Ternary | undefined = expanding ? Ternary.Maybe : undefined; + if (skipTrue || expanding || (localResult = isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.trueType), distributionMapper) : getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false))) { + if (!skipFalse && !expanding) { + localResult = (localResult || Ternary.Maybe) & isRelatedTo(source, distributionMapper ? instantiateType(getTypeFromTypeNode(c.root.node.falseType), distributionMapper) : getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); } } if (localResult) { @@ -18697,6 +19056,9 @@ namespace ts { } else if (target.flags & TypeFlags.TemplateLiteral) { if (source.flags & TypeFlags.TemplateLiteral) { + if (relation === comparableRelation) { + return templateLiteralTypesDefinitelyUnrelated(source as TemplateLiteralType, target as TemplateLiteralType) ? Ternary.False : Ternary.True; + } // Report unreliable variance for type variables referenced in template literal type placeholders. // For example, `foo-${number}` is related to `foo-${string}` even though number isn't related to string. instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); @@ -18713,34 +19075,33 @@ namespace ts { const constraint = getConstraintOfType(source as TypeVariable); if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { // A type variable with no constraint is not related to the non-primitive object type. - if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive), RecursionFlags.Both)) { resetErrorInfo(saveErrorInfo); return result; } } // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed - else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors && !(target.flags & source.flags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(target.flags & source.flags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } } } else if (source.flags & TypeFlags.Index) { - if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) { + if (result = isRelatedTo(keyofConstraintType, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } - else if (source.flags & TypeFlags.TemplateLiteral) { + else if (source.flags & TypeFlags.TemplateLiteral && !(target.flags & TypeFlags.Object)) { if (!(target.flags & TypeFlags.TemplateLiteral)) { - const baseConstraint = getBaseConstraintOfType(source); - const constraint = baseConstraint && baseConstraint !== source ? baseConstraint : stringType; - if (result = isRelatedTo(constraint, target, reportErrors)) { + const constraint = getBaseConstraintOfType(source); + if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) { resetErrorInfo(saveErrorInfo); return result; } @@ -18748,14 +19109,14 @@ namespace ts { } else if (source.flags & TypeFlags.StringMapping) { if (target.flags & TypeFlags.StringMapping && (source as StringMappingType).symbol === (target as StringMappingType).symbol) { - if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, reportErrors)) { + if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } else { const constraint = getBaseConstraintOfType(source); - if (constraint && (result = isRelatedTo(constraint, target, reportErrors))) { + if (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) { resetErrorInfo(saveErrorInfo); return result; } @@ -18763,27 +19124,32 @@ namespace ts { } else if (source.flags & TypeFlags.Conditional) { if (target.flags & TypeFlags.Conditional) { - // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if - // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, - // and Y1 is related to Y2. - const sourceParams = (source as ConditionalType).root.inferTypeParameters; - let sourceExtends = (source as ConditionalType).extendsType; - let mapper: TypeMapper | undefined; - if (sourceParams) { - // If the source has infer type parameters, we instantiate them in the context of the target - const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedTo); - inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); - sourceExtends = instantiateType(sourceExtends, ctx.mapper); - mapper = ctx.mapper; - } - if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && - (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType))) { - if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), reportErrors)) { - result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), reportErrors); - } - if (result) { - resetErrorInfo(saveErrorInfo); - return result; + // If one of the conditionals under comparison seems to be infinitely expanding, stop comparing it - back out, try + // the constraint, and failing that, give up trying to relate the two. This is the only way we can handle recursive conditional + // types, which might expand forever. + if (!isDeeplyNestedType(source, sourceStack, sourceDepth) && !isDeeplyNestedType(target, targetStack, targetDepth)) { + // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if + // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, + // and Y1 is related to Y2. + const sourceParams = (source as ConditionalType).root.inferTypeParameters; + let sourceExtends = (source as ConditionalType).extendsType; + let mapper: TypeMapper | undefined; + if (sourceParams) { + // If the source has infer type parameters, we instantiate them in the context of the target + const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedToWorker); + inferTypes(ctx.inferences, (target as ConditionalType).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + sourceExtends = instantiateType(sourceExtends, ctx.mapper); + mapper = ctx.mapper; + } + if (isTypeIdenticalTo(sourceExtends, (target as ConditionalType).extendsType) && + (isRelatedTo((source as ConditionalType).checkType, (target as ConditionalType).checkType, RecursionFlags.Both) || isRelatedTo((target as ConditionalType).checkType, (source as ConditionalType).checkType, RecursionFlags.Both))) { + if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source as ConditionalType), mapper), getTrueTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors)) { + result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors); + } + if (result) { + resetErrorInfo(saveErrorInfo); + return result; + } } } } @@ -18792,19 +19158,25 @@ namespace ts { // more assignments than are desirable (since it maps the source check type to its constraint, it loses information) const distributiveConstraint = getConstraintOfDistributiveConditionalType(source as ConditionalType); if (distributiveConstraint) { - if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) { + if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) { resetErrorInfo(saveErrorInfo); return result; } } } - // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` - // when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!). - const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); - if (defaultConstraint) { - if (result = isRelatedTo(defaultConstraint, target, reportErrors)) { - resetErrorInfo(saveErrorInfo); - return result; + + + // We'll repeatedly decompose source side conditionals if they're recursive - check if we've already recured on the constraint a lot and, if so, bail + // on the comparison. + if (!isDeeplyNestedType(source, sourceStack, sourceDepth)) { + // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` + // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). + const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); + if (defaultConstraint) { + if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) { + resetErrorInfo(saveErrorInfo); + return result; + } } } } @@ -18848,7 +19220,7 @@ namespace ts { } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { if (relation !== identityRelation) { - return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, reportErrors); + return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors); } else { // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple @@ -18974,10 +19346,10 @@ namespace ts { let result: Ternary; const targetConstraint = getConstraintTypeFromMappedType(target); const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers)); - if (result = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) { + if (result = isRelatedTo(targetConstraint, sourceConstraint, RecursionFlags.Both, reportErrors)) { const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]); if (instantiateType(getNameTypeFromMappedType(source), mapper) === instantiateType(getNameTypeFromMappedType(target), mapper)) { - return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors); + return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), RecursionFlags.Both, reportErrors); } } } @@ -19099,7 +19471,7 @@ namespace ts { const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ false, targetIsOptional); const effectiveSource = getTypeOfSourceProperty(sourceProp); - return isRelatedTo(effectiveSource, effectiveTarget, reportErrors, /*headMessage*/ undefined, intersectionState); + return isRelatedTo(effectiveSource, effectiveTarget, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState, skipOptional: boolean): Ternary { @@ -19293,7 +19665,7 @@ namespace ts { const targetType = targetTypeArguments[i]; const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); - const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); + const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors && (targetArity > 1 || sourceArity > 1)) { if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { @@ -19493,7 +19865,7 @@ namespace ts { */ function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary { return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, - relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, makeFunctionTypeMapper(reportUnreliableMarkers)); + relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedToWorker, makeFunctionTypeMapper(reportUnreliableMarkers)); } function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary { @@ -19527,7 +19899,7 @@ namespace ts { const type = exactOptionalPropertyTypes || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); - const related = isRelatedTo(type, targetInfo.type, reportErrors); + const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related) { if (reportErrors) { reportError(Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); @@ -19550,7 +19922,7 @@ namespace ts { } function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean) { - const related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); + const related = isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related && reportErrors) { if (sourceInfo.keyType === targetInfo.keyType) { reportError(Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType)); @@ -19571,7 +19943,7 @@ namespace ts { let result = Ternary.True; for (const targetInfo of indexInfos) { const related = !sourceIsPrimitive && targetHasStringIndex && targetInfo.type.flags & TypeFlags.Any ? Ternary.True : - isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors) : + isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, RecursionFlags.Both, reportErrors) : typeRelatedToIndexInfo(source, targetInfo, reportErrors, intersectionState); if (!related) { return Ternary.False; @@ -19604,7 +19976,7 @@ namespace ts { } for (const targetInfo of targetInfos) { const sourceInfo = getIndexInfoOfType(source, targetInfo.keyType); - if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type) && sourceInfo.isReadonly === targetInfo.isReadonly)) { + if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both) && sourceInfo.isReadonly === targetInfo.isReadonly)) { return Ternary.False; } } @@ -21111,6 +21483,18 @@ namespace ts { return !!(type.symbol && some(type.symbol.declarations, hasSkipDirectInferenceFlag)); } + function templateLiteralTypesDefinitelyUnrelated(source: TemplateLiteralType, target: TemplateLiteralType) { + // Two template literal types with diffences in their starting or ending text spans are definitely unrelated. + const sourceStart = source.texts[0]; + const targetStart = target.texts[0]; + const sourceEnd = source.texts[source.texts.length - 1]; + const targetEnd = target.texts[target.texts.length - 1]; + const startLen = Math.min(sourceStart.length, targetStart.length); + const endLen = Math.min(sourceEnd.length, targetEnd.length); + return sourceStart.slice(0, startLen) !== targetStart.slice(0, startLen) || + sourceEnd.slice(sourceEnd.length - endLen) !== targetEnd.slice(targetEnd.length - endLen); + } + function isValidBigIntString(s: string): boolean { const scanner = createScanner(ScriptTarget.ESNext, /*skipTrivia*/ false); let success = true; @@ -21701,8 +22085,16 @@ namespace ts { function inferToTemplateLiteralType(source: Type, target: TemplateLiteralType) { const matches = inferTypesFromTemplateLiteralType(source, target); const types = target.types; - for (let i = 0; i < types.length; i++) { - inferFromTypes(matches ? matches[i] : neverType, types[i]); + // When the target template literal contains only placeholders (meaning that inference is intended to extract + // single characters and remainder strings) and inference fails to produce matches, we want to infer 'never' for + // each placeholder such that instantiation with the inferred value(s) produces 'never', a type for which an + // assignment check will fail. If we make no inferences, we'll likely end up with the constraint 'string' which, + // upon instantiation, would collapse all the placeholders to just 'string', and an assignment check might + // succeed. That would be a pointless and confusing outcome. + if (matches || every(target.texts, s => s.length === 0)) { + for (let i = 0; i < types.length; i++) { + inferFromTypes(matches ? matches[i] : neverType, types[i]); + } } } @@ -22058,8 +22450,7 @@ namespace ts { getCannotFindNameDiagnosticForName(node), node, !isWriteOnlyAccess(node), - /*excludeGlobals*/ false, - /*issueSuggestions*/ true) || unknownSymbol; + /*excludeGlobals*/ false) || unknownSymbol; } return links.resolvedSymbol; } @@ -22144,13 +22535,6 @@ namespace ts { return false; } - // Given a source x, check if target matches x or is an && operation with an operand that matches x. - function containsTruthyCheck(source: Node, target: Node): boolean { - return isMatchingReference(source, target) || - (target.kind === SyntaxKind.BinaryExpression && (target as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && - (containsTruthyCheck(source, (target as BinaryExpression).left) || containsTruthyCheck(source, (target as BinaryExpression).right))); - } - function getPropertyAccess(expr: Expression) { if (isAccessExpression(expr)) { return expr; @@ -22210,7 +22594,7 @@ namespace ts { if ((prop as TransientSymbol).isDiscriminantProperty === undefined) { (prop as TransientSymbol).isDiscriminantProperty = ((prop as TransientSymbol).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant && - !maybeTypeOfKind(getTypeOfSymbol(prop), TypeFlags.Instantiable & ~TypeFlags.TemplateLiteral); + !isGenericType(getTypeOfSymbol(prop)); } return !!(prop as TransientSymbol).isDiscriminantProperty; } @@ -22769,15 +23153,17 @@ namespace ts { return filterType(type, t => (t.flags & kind) !== 0); } - // Return a new type in which occurrences of the string and number primitive types in - // typeWithPrimitives have been replaced with occurrences of string literals and numeric - // literals in typeWithLiterals, respectively. + // Return a new type in which occurrences of the string, number and bigint primitives and placeholder template + // literal types in typeWithPrimitives have been replaced with occurrences of compatible and more specific types + // from typeWithLiterals. This is essentially a limited form of intersection between the two types. We avoid a + // true intersection because it is more costly and, when applied to union types, generates a large number of + // types we don't actually care about. function replacePrimitivesWithLiterals(typeWithPrimitives: Type, typeWithLiterals: Type) { - if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral) || - isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.NumberLiteral) || - isTypeSubsetOf(bigintType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, TypeFlags.BigIntLiteral)) { + if (maybeTypeOfKind(typeWithPrimitives, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.Number | TypeFlags.BigInt) && + maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.NumberLiteral | TypeFlags.BigIntLiteral)) { return mapType(typeWithPrimitives, t => - t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral) : + t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) : + isPatternLiteralType(t) && !maybeTypeOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? extractTypesOfKind(typeWithLiterals, TypeFlags.StringLiteral) : t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) : t.flags & TypeFlags.BigInt ? extractTypesOfKind(typeWithLiterals, TypeFlags.BigInt | TypeFlags.BigIntLiteral) : t); } @@ -22872,10 +23258,10 @@ namespace ts { return isLengthPushOrUnshift || isElementAssignment; } - function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration) { - return (declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter || - declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) && - !!getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature); + function isDeclarationWithExplicitTypeAnnotation(node: Declaration) { + return (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isParameter(node)) && + !!(getEffectiveTypeAnnotationNode(node) || + isInJSFile(node) && hasInitializer(node) && node.initializer && isFunctionExpressionOrArrowFunction(node.initializer) && getEffectiveReturnTypeNode(node.initializer)); } function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) { @@ -23129,9 +23515,10 @@ namespace ts { function isConstantReference(node: Node): boolean { switch (node.kind) { - case SyntaxKind.Identifier: + case SyntaxKind.Identifier: { const symbol = getResolvedSymbol(node as Identifier); - return isConstVariable(symbol) || !!symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration).kind === SyntaxKind.Parameter && !isParameterAssigned(symbol); + return isConstVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol); + } case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: // The resolvedSymbol property is initialized by checkPropertyAccess or checkElementAccess before we get here. @@ -23144,7 +23531,6 @@ namespace ts { let key: string | undefined; let isKeySet = false; let flowDepth = 0; - let inlineLevel = 0; if (flowAnalysisDisabled) { return errorType; } @@ -23163,7 +23549,8 @@ namespace ts { if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } - return resultType; + // The non-null unknown type should never escape control flow analysis. + return resultType === nonNullUnknownType ? unknownType : resultType; function getOrSetCacheKey() { if (isKeySet) { @@ -23619,7 +24006,7 @@ namespace ts { const narrowedPropType = narrowType(propType); return filterType(type, t => { const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(discriminantType.flags & TypeFlags.Never) && isTypeComparableTo(discriminantType, narrowedPropType); + return !(narrowedPropType.flags & TypeFlags.Never) && isTypeComparableTo(narrowedPropType, discriminantType); }); } @@ -23651,7 +24038,8 @@ namespace ts { function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type { if (isMatchingReference(reference, expr)) { - return getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); + return type.flags & TypeFlags.Unknown && assumeTrue ? nonNullUnknownType : + getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); } if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) { type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); @@ -23733,6 +24121,9 @@ namespace ts { case SyntaxKind.InstanceOfKeyword: return narrowTypeByInstanceof(type, expr, assumeTrue); case SyntaxKind.InKeyword: + if (isPrivateIdentifier(expr.left)) { + return narrowTypeByPrivateIdentifierInInExpression(type, expr, assumeTrue); + } const target = getReferenceCandidate(expr.right); const leftType = getTypeOfNode(expr.left); if (leftType.flags & TypeFlags.StringLiteral) { @@ -23763,6 +24154,24 @@ namespace ts { return type; } + function narrowTypeByPrivateIdentifierInInExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { + const target = getReferenceCandidate(expr.right); + if (!isMatchingReference(reference, target)) { + return type; + } + + Debug.assertNode(expr.left, isPrivateIdentifier); + const symbol = getSymbolForPrivateIdentifierExpression(expr.left); + if (symbol === undefined) { + return type; + } + const classSymbol = symbol.parent!; + const targetType = hasStaticModifier(Debug.checkDefined(symbol.valueDeclaration, "should always have a declaration")) + ? getTypeOfSymbol(classSymbol) as InterfaceType + : getDeclaredTypeOfSymbol(classSymbol); + return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); + } + function narrowTypeByOptionalChainContainment(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { // We are in a branch of obj?.foo === value (or any one of the other equality operators). We narrow obj as follows: // When operator is === and type of value excludes undefined, null and undefined is removed from type of obj in true branch. @@ -23790,6 +24199,9 @@ namespace ts { assumeTrue = !assumeTrue; } const valueType = getTypeOfExpression(value); + if (assumeTrue && (type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken) && (valueType.flags & TypeFlags.Null)) { + return getUnionType([nullType, undefinedType]); + } if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) { if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) { return valueType; @@ -23809,7 +24221,7 @@ namespace ts { valueType.flags & TypeFlags.Null ? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; - return getTypeWithFacts(type, facts); + return type.flags & TypeFlags.Unknown && facts & (TypeFacts.NENull | TypeFacts.NEUndefinedOrNull) ? nonNullUnknownType : getTypeWithFacts(type, facts); } if (assumeTrue) { const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? @@ -23839,15 +24251,10 @@ namespace ts { return type; } if (assumeTrue && type.flags & TypeFlags.Unknown && literal.text === "object") { - // The pattern x && typeof x === 'object', where x is of type unknown, narrows x to type object. We don't - // need to check for the reverse typeof x === 'object' && x since that already narrows correctly. - if (typeOfExpr.parent.parent.kind === SyntaxKind.BinaryExpression) { - const expr = typeOfExpr.parent.parent as BinaryExpression; - if (expr.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && expr.right === typeOfExpr.parent && containsTruthyCheck(reference, expr.left)) { - return nonPrimitiveType; - } - } - return getUnionType([nonPrimitiveType, nullType]); + // The non-null unknown type is used to track whether a previous narrowing operation has removed the null type + // from the unknown type. For example, the expression `x && typeof x === 'object'` first narrows x to the non-null + // unknown type, and then narrows that to the non-primitive type. + return type === nonNullUnknownType ? nonPrimitiveType : getUnionType([nonPrimitiveType, nullType]); } const facts = assumeTrue ? typeofEQFacts.get(literal.text) || TypeFacts.TypeofEQHostObject : @@ -24101,16 +24508,7 @@ namespace ts { function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, isRelated: (source: Type, target: Type) => boolean) { if (!assumeTrue) { - return filterType(type, t => { - if (!isRelated(t, candidate)) { - return true; - } - const constraint = getBaseConstraintOfType(t); - if (constraint && constraint !== t) { - return !isRelated(constraint, candidate); - } - return false; - }); + return filterType(type, t => !isRelated(t, candidate)); } // If the current type is a union type, remove all constituents that couldn't be instances of // the candidate type. If one or more constituents remain, return a union of those. @@ -24269,37 +24667,38 @@ namespace ts { node.kind === SyntaxKind.PropertyDeclaration)!; } - // Check if a parameter is assigned anywhere within its declaring function. - function isParameterAssigned(symbol: Symbol) { + // Check if a parameter or catch variable is assigned anywhere + function isSymbolAssigned(symbol: Symbol) { if (!symbol.valueDeclaration) { return false; } - const func = getRootDeclaration(symbol.valueDeclaration).parent as FunctionLikeDeclaration; - const links = getNodeLinks(func); + const parent = getRootDeclaration(symbol.valueDeclaration).parent; + const links = getNodeLinks(parent); if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) { links.flags |= NodeCheckFlags.AssignmentsMarked; - if (!hasParentWithAssignmentsMarked(func)) { - markParameterAssignments(func); + if (!hasParentWithAssignmentsMarked(parent)) { + markNodeAssignments(parent); } } return symbol.isAssigned || false; } function hasParentWithAssignmentsMarked(node: Node) { - return !!findAncestor(node.parent, node => isFunctionLike(node) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked)); + return !!findAncestor(node.parent, node => + (isFunctionLike(node) || isCatchClause(node)) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked)); } - function markParameterAssignments(node: Node) { + function markNodeAssignments(node: Node) { if (node.kind === SyntaxKind.Identifier) { if (isAssignmentTarget(node)) { const symbol = getResolvedSymbol(node as Identifier); - if (symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration).kind === SyntaxKind.Parameter) { + if (isParameterOrCatchClauseVariable(symbol)) { symbol.isAssigned = true; } } } else { - forEachChild(node, markParameterAssignments); + forEachChild(node, markNodeAssignments); } } @@ -24368,7 +24767,19 @@ namespace ts { } function isExportOrExportExpression(location: Node) { - return !!findAncestor(location, e => e.parent && isExportAssignment(e.parent) && e.parent.expression === e && isEntityNameExpression(e)); + return !!findAncestor(location, n => { + const parent = n.parent; + if (parent === undefined) { + return "quit"; + } + if (isExportAssignment(parent)) { + return parent.expression === n && isEntityNameExpression(n); + } + if (isExportSpecifier(parent)) { + return parent.name === n || parent.propertyName === n; + } + return false; + }); } function markAliasReferenced(symbol: Symbol, location: Node) { @@ -24537,7 +24948,7 @@ namespace ts { // analysis to include the immediately enclosing function. while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression || flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethodOrAccessor(flowContainer)) && - (isConstVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isParameterAssigned(localOrExportSymbol))) { + (isConstVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isSymbolAssigned(localOrExportSymbol))) { flowContainer = getControlFlowContainer(flowContainer); } // We only look for uninitialized variables in strict null checking mode, and only when we can analyze @@ -25335,7 +25746,8 @@ namespace ts { } if (functionFlags & FunctionFlags.Async) { // Async function or AsyncGenerator function - const contextualAwaitedType = mapType(contextualReturnType, getAwaitedType); + // Get the awaited type without the `Awaited` alias + const contextualAwaitedType = mapType(contextualReturnType, getAwaitedTypeNoAlias); return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]); } @@ -25348,7 +25760,7 @@ namespace ts { function getContextualTypeForAwaitOperand(node: AwaitExpression, contextFlags?: ContextFlags): Type | undefined { const contextualType = getContextualType(node, contextFlags); if (contextualType) { - const contextualAwaitedType = getAwaitedType(contextualType); + const contextualAwaitedType = getAwaitedTypeNoAlias(contextualType); return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]); } return undefined; @@ -25424,6 +25836,12 @@ namespace ts { } function getContextualTypeForArgumentAtIndex(callTarget: CallLikeExpression, argIndex: number): Type { + if (isImportCall(callTarget)) { + return argIndex === 0 ? stringType : + argIndex === 1 ? getGlobalImportCallOptionsType(/*reportErrors*/ false) : + anyType; + } + // If we're already in the process of resolving the given signature, don't resolve again as // that could cause infinite recursion. Instead, return anySignature. const signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget); @@ -25884,10 +26302,6 @@ namespace ts { case SyntaxKind.AwaitExpression: return getContextualTypeForAwaitOperand(parent as AwaitExpression, contextFlags); case SyntaxKind.CallExpression: - if ((parent as CallExpression).expression.kind === SyntaxKind.ImportKeyword) { - return stringType; - } - /* falls through */ case SyntaxKind.NewExpression: return getContextualTypeForArgument(parent as CallExpression | NewExpression, node); case SyntaxKind.TypeAssertionExpression: @@ -25960,7 +26374,7 @@ namespace ts { let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType); propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType); const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); - if (intrinsicAttribs !== errorType) { + if (!isErrorType(intrinsicAttribs)) { propsType = intersectTypes(intrinsicAttribs, propsType); } return propsType; @@ -26059,7 +26473,7 @@ namespace ts { // Normal case -- add in IntrinsicClassElements and IntrinsicElements let apparentAttributesType = attributesType; const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context); - if (intrinsicClassAttribs !== errorType) { + if (!isErrorType(intrinsicClassAttribs)) { const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol); const hostClassType = getReturnTypeOfSignature(sig); apparentAttributesType = intersectTypes( @@ -26071,7 +26485,7 @@ namespace ts { } const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); - if (intrinsicAttribs !== errorType) { + if (!isErrorType(intrinsicAttribs)) { apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType); } @@ -26199,10 +26613,6 @@ namespace ts { return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount; } - function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction { - return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction; - } - function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature | undefined { // Only function expressions, arrow functions, and object literal methods are contextually typed. return isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node) @@ -26582,7 +26992,7 @@ namespace ts { checkSpreadPropOverrides(mergedType, allPropertiesTable, memberDecl); } offset = propertiesArray.length; - if (spread === errorType) { + if (isErrorType(spread)) { continue; } spread = getSpreadType(spread, mergedType, node.symbol, objectFlags, inConstContext); @@ -26642,7 +27052,7 @@ namespace ts { } } - if (spread === errorType) { + if (isErrorType(spread)) { return errorType; } @@ -26936,7 +27346,7 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedSymbol) { const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node); - if (intrinsicElementsType !== errorType) { + if (!isErrorType(intrinsicElementsType)) { // Property case if (!isIdentifier(node.tagName)) return Debug.fail(); const intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText); @@ -27110,7 +27520,7 @@ namespace ts { // var CustomTag: "h1" = "h1"; // Hello World const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, location); - if (intrinsicElementsType !== errorType) { + if (!isErrorType(intrinsicElementsType)) { const stringLiteralTypeName = type.value; const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { @@ -27182,7 +27592,7 @@ namespace ts { function getJsxElementClassTypeAt(location: Node): Type | undefined { const type = getJsxType(JsxNames.ElementClass, location); - if (type === errorType) return undefined; + if (isErrorType(type)) return undefined; return type; } @@ -27250,6 +27660,15 @@ namespace ts { markAliasSymbolAsReferenced(jsxFactorySym); } } + + // For JsxFragment, mark jsx pragma as referenced via resolveName + if (isJsxOpeningFragment(node)) { + const file = getSourceFileOfNode(node); + const localJsxNamespace = getLocalJsxNamespace(file); + if (localJsxNamespace) { + resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, localJsxNamespace, /*isUse*/ true); + } + } } if (isNodeOpeningLikeElement) { @@ -27551,7 +27970,7 @@ namespace ts { function checkNonNullNonVoidType(type: Type, node: Node): Type { const nonNullType = checkNonNullType(type, node); - if (nonNullType !== errorType && nonNullType.flags & TypeFlags.Void) { + if (nonNullType.flags & TypeFlags.Void) { error(node, Diagnostics.Object_is_possibly_undefined); } return nonNullType; @@ -27592,6 +28011,40 @@ namespace ts { } } + function checkGrammarPrivateIdentifierExpression(privId: PrivateIdentifier): boolean { + if (!getContainingClass(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + } + if (!isExpressionNode(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression); + } + if (!getSymbolForPrivateIdentifierExpression(privId)) { + return grammarErrorOnNode(privId, Diagnostics.Cannot_find_name_0, idText(privId)); + } + return false; + } + + function checkPrivateIdentifierExpression(privId: PrivateIdentifier): Type { + checkGrammarPrivateIdentifierExpression(privId); + const symbol = getSymbolForPrivateIdentifierExpression(privId); + if (symbol) { + markPropertyAsReferenced(symbol, /* nodeForCheckWriteOnly: */ undefined, /* isThisAccess: */ false); + } + return anyType; + } + + function getSymbolForPrivateIdentifierExpression(privId: PrivateIdentifier): Symbol | undefined { + if (!isExpressionNode(privId)) { + return undefined; + } + + const links = getNodeLinks(privId); + if (links.resolvedSymbol === undefined) { + links.resolvedSymbol = lookupSymbolForPrivateIdentifierDeclaration(privId.escapedText, privId); + } + return links.resolvedSymbol; + } + function getPrivateIdentifierPropertyOfType(leftType: Type, lexicallyScopedIdentifier: Symbol): Symbol | undefined { return getPropertyOfType(leftType, lexicallyScopedIdentifier.escapedName); } @@ -27683,7 +28136,7 @@ namespace ts { grammarErrorOnNode(right, Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, idText(right)); } - if (lexicallyScopedSymbol?.valueDeclaration && (compilerOptions.target === ScriptTarget.ESNext && !useDefineForClassFields)) { + if (lexicallyScopedSymbol?.valueDeclaration && (getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && !useDefineForClassFields)) { const lexicalClass = getContainingClass(lexicallyScopedSymbol.valueDeclaration); const parentStaticFieldInitializer = findAncestor(node, (n) => { if (n === lexicalClass) return "quit"; @@ -27708,7 +28161,7 @@ namespace ts { if (isAnyLike) { if (lexicallyScopedSymbol) { - return apparentType; + return isErrorType(apparentType) ? errorType : apparentType; } if (!getContainingClass(right)) { grammarErrorOnNode(right, Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); @@ -27732,7 +28185,7 @@ namespace ts { if (isIdentifier(left) && parentSymbol) { markAliasReferenced(parentSymbol, node); } - return apparentType; + return isErrorType(apparentType) ? errorType : apparentType;; } prop = getPropertyOfType(apparentType, right.escapedText); } @@ -28082,7 +28535,20 @@ namespace ts { // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. - return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning); + if (symbol) return symbol; + let candidates: Symbol[]; + if (symbols === globals) { + const primitives = mapDefined( + ["string", "number", "boolean", "object", "bigint", "symbol"], + s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String) + ? createSymbol(SymbolFlags.TypeAlias, s as __String) as Symbol + : undefined); + candidates = primitives.concat(arrayFrom(symbols.values())); + } + else { + candidates = arrayFrom(symbols.values()); + } + return getSpellingSuggestionForName(unescapeLeadingUnderscores(name), candidates, meaning); }); return result; } @@ -28128,6 +28594,11 @@ namespace ts { return suggestion; } + function getSuggestedTypeForNonexistentStringLiteralType(source: StringLiteralType, target: UnionType): StringLiteralType | undefined { + const candidates = target.types.filter((type): type is StringLiteralType => !!(type.flags & TypeFlags.StringLiteral)); + return getSpellingSuggestion(source.value, candidates, type => type.value); + } + /** * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough. * Names less than length 3 only check for case-insensitive equality, not levenshtein distance. @@ -28233,7 +28704,7 @@ namespace ts { type: Type): boolean { // Short-circuiting for improved performance. - if (type === errorType || isTypeAny(type)) { + if (isTypeAny(type)) { return true; } @@ -28259,7 +28730,7 @@ namespace ts { property: Symbol): boolean { // Short-circuiting for improved performance. - if (containingType === errorType || isTypeAny(containingType)) { + if (isTypeAny(containingType)) { return true; } @@ -28339,7 +28810,7 @@ namespace ts { const indexExpression = node.argumentExpression; const indexType = checkExpression(indexExpression); - if (objectType === errorType || objectType === silentNeverType) { + if (isErrorType(objectType) || objectType === silentNeverType) { return objectType; } @@ -29642,7 +30113,7 @@ namespace ts { } return anySignature; } - if (superType !== errorType) { + if (!isErrorType(superType)) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!); @@ -29678,7 +30149,7 @@ namespace ts { } const apparentType = getApparentType(funcType); - if (apparentType === errorType) { + if (isErrorType(apparentType)) { // Another error has already been reported return resolveErrorCall(node); } @@ -29696,7 +30167,7 @@ namespace ts { if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) { // The unknownType indicates that an error already occurred (and was reported). No // need to report another error in this case. - if (funcType !== errorType && node.typeArguments) { + if (!isErrorType(funcType) && node.typeArguments) { error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); @@ -29779,7 +30250,7 @@ namespace ts { // signatures for overload resolution. The result type of the function call becomes // the result type of the operation. expressionType = getApparentType(expressionType); - if (expressionType === errorType) { + if (isErrorType(expressionType)) { // Another error has already been reported return resolveErrorCall(node); } @@ -30032,7 +30503,7 @@ namespace ts { const tagType = checkExpression(node.tag); const apparentType = getApparentType(tagType); - if (apparentType === errorType) { + if (isErrorType(apparentType)) { // Another error has already been reported return resolveErrorCall(node); } @@ -30089,7 +30560,7 @@ namespace ts { function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { const funcType = checkExpression(node.expression); const apparentType = getApparentType(funcType); - if (apparentType === errorType) { + if (isErrorType(apparentType)) { return resolveErrorCall(node); } @@ -30159,7 +30630,7 @@ namespace ts { } const exprTypes = checkExpression(node.tagName); const apparentType = getApparentType(exprTypes); - if (apparentType === errorType) { + if (isErrorType(apparentType)) { return resolveErrorCall(node); } @@ -30478,10 +30949,12 @@ namespace ts { if (node.arguments.length === 0) { return createPromiseReturnType(node, anyType); } + const specifier = node.arguments[0]; const specifierType = checkExpressionCached(specifier); + const optionsType = node.arguments.length > 1 ? checkExpressionCached(node.arguments[1]) : undefined; // Even though multiple arguments is grammatically incorrect, type-check extra arguments for completion - for (let i = 1; i < node.arguments.length; ++i) { + for (let i = 2; i < node.arguments.length; ++i) { checkExpressionCached(node.arguments[i]); } @@ -30489,23 +30962,30 @@ namespace ts { error(specifier, Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType)); } + if (optionsType) { + const importCallOptionsType = getGlobalImportCallOptionsType(/*reportErrors*/ true); + if (importCallOptionsType !== emptyObjectType) { + checkTypeAssignableTo(optionsType, getNullableType(importCallOptionsType, TypeFlags.Undefined), node.arguments[1]); + } + } + // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal const moduleSymbol = resolveExternalModuleName(node, specifier); if (moduleSymbol) { const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true, /*suppressUsageError*/ false); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol, specifier)); } } return createPromiseReturnType(node, anyType); } - function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol): Type { - if (allowSyntheticDefaultImports && type && type !== errorType) { + function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol, moduleSpecifier: Expression): Type { + if (allowSyntheticDefaultImports && type && !isErrorType(type)) { const synthType = type as SyntheticDefaultModuleType; if (!synthType.syntheticType) { const file = originalSymbol.declarations?.find(isSourceFile); - const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false); + const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false, moduleSpecifier); if (hasSyntheticDefault) { const memberTable = createSymbolTable(); const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default); @@ -30567,6 +31047,12 @@ namespace ts { } function checkAssertion(node: AssertionExpression) { + if (node.kind === SyntaxKind.TypeAssertionExpression) { + const file = getSourceFileOfNode(node); + if (file && fileExtensionIsOneOf(file.fileName, [Extension.Cts, Extension.Mts])) { + grammarErrorOnNode(node, Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead); + } + } return checkAssertionWorker(node, node.type, node.expression); } @@ -30592,13 +31078,11 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: const expr = (node as PropertyAccessExpression | ElementAccessExpression).expression; - if (isIdentifier(expr)) { - let symbol = getSymbolAtLocation(expr); - if (symbol && symbol.flags & SymbolFlags.Alias) { - symbol = resolveAlias(symbol); - } - return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal); + let symbol = getTypeOfNode(expr).symbol; + if (symbol && symbol.flags & SymbolFlags.Alias) { + symbol = resolveAlias(symbol); } + return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal); } return false; } @@ -30614,7 +31098,7 @@ namespace ts { checkSourceElement(type); exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(exprType)); const targetType = getTypeFromTypeNode(type); - if (produceDiagnostics && targetType !== errorType) { + if (produceDiagnostics && !isErrorType(targetType)) { const widenedType = getWidenedType(exprType); if (!isTypeComparableTo(targetType, widenedType)) { checkTypeComparableTo(exprType, targetType, errNode, @@ -30655,7 +31139,7 @@ namespace ts { return getGlobalImportMetaExpressionType(); case SyntaxKind.NewKeyword: const type = checkNewTargetMetaProperty(node); - return type === errorType ? errorType : createNewTargetExpressionType(type); + return isErrorType(type) ? errorType : createNewTargetExpressionType(type); default: Debug.assertNever(node.keywordToken); } @@ -30678,8 +31162,13 @@ namespace ts { } function checkImportMetaProperty(node: MetaProperty) { - if (moduleKind !== ModuleKind.ES2020 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) { - error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_esnext_or_system); + if (moduleKind === ModuleKind.Node12 || moduleKind === ModuleKind.NodeNext) { + if (getSourceFileOfNode(node).impliedNodeFormat !== ModuleKind.ESNext) { + error(node, Diagnostics.The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output); + } + } + else if (moduleKind < ModuleKind.ES2020 && moduleKind !== ModuleKind.System) { + error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node12_or_nodenext); } const file = getSourceFileOfNode(node); Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); @@ -31008,7 +31497,8 @@ namespace ts { const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type - promisedType = getAwaitedType(promisedType) || unknownType; + // Unwrap an `Awaited` to `T` to improve inference. + promisedType = getAwaitedTypeNoAlias(unwrapAwaitedType(promisedType)) || unknownType; return createTypeReference(globalPromiseType, [promisedType]); } @@ -31020,7 +31510,8 @@ namespace ts { const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true); if (globalPromiseLikeType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type - promisedType = getAwaitedType(promisedType) || unknownType; + // Unwrap an `Awaited` to `T` to improve inference. + promisedType = getAwaitedTypeNoAlias(unwrapAwaitedType(promisedType)) || unknownType; return createTypeReference(globalPromiseLikeType, [promisedType]); } @@ -31077,7 +31568,7 @@ namespace ts { // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which we will wrap in // the native Promise type later in this function. - returnType = checkAwaitedType(returnType, /*errorNode*/ func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + returnType = unwrapAwaitedType(checkAwaitedType(returnType, /*withAlias*/ false, /*errorNode*/ func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); } } else if (isGenerator) { // Generator or AsyncGenerator function @@ -31310,7 +31801,7 @@ namespace ts { // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which should be wrapped in // the native Promise type by the caller. - type = checkAwaitedType(type, func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + type = unwrapAwaitedType(checkAwaitedType(type, /*withAlias*/ false, func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)); } if (type.flags & TypeFlags.Never) { hasReturnOfTypeNever = true; @@ -31512,7 +32003,7 @@ namespace ts { const returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags); if (returnOrPromisedType) { if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function - const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + const awaitedType = checkAwaitedType(exprType, /*withAlias*/ false, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body); } else { // Normal function @@ -31700,10 +32191,10 @@ namespace ts { Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); diagnostics.add(diagnostic); } - if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || languageVersion < ScriptTarget.ES2017) { + if ((moduleKind !== ModuleKind.ES2022 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System && !(moduleKind === ModuleKind.NodeNext && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.ESNext)) || languageVersion < ScriptTarget.ES2017) { span = getSpanOfTokenAtPosition(sourceFile, node.pos); const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, - Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); + Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -31729,8 +32220,8 @@ namespace ts { } const operandType = checkExpression(node.expression); - const awaitedType = checkAwaitedType(operandType, node, Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); - if (awaitedType === operandType && awaitedType !== errorType && !(operandType.flags & TypeFlags.AnyOrUnknown)) { + const awaitedType = checkAwaitedType(operandType, /*withAlias*/ true, node, Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + if (awaitedType === operandType && !isErrorType(awaitedType) && !(operandType.flags & TypeFlags.AnyOrUnknown)) { addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(node, Diagnostics.await_has_no_effect_on_the_type_of_this_expression)); } return awaitedType; @@ -31898,11 +32389,29 @@ namespace ts { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } - leftType = checkNonNullType(leftType, left); + if (isPrivateIdentifier(left)) { + if (languageVersion < ScriptTarget.ESNext) { + checkExternalEmitHelpers(left, ExternalEmitHelpers.ClassPrivateFieldIn); + } + // Unlike in 'checkPrivateIdentifierExpression' we now have access to the RHS type + // which provides us with the opportunity to emit more detailed errors + if (!getNodeLinks(left).resolvedSymbol && getContainingClass(left)) { + const isUncheckedJS = isUncheckedJSSuggestion(left, rightType.symbol, /*excludeClasses*/ true); + reportNonexistentProperty(left, rightType, isUncheckedJS); + } + } + else { + leftType = checkNonNullType(leftType, left); + // TypeScript 1.0 spec (April 2014): 4.15.5 + // Require the left operand to be of type Any, the String primitive type, or the Number primitive type. + if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) || + isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.TypeParameter))) { + error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_a_private_identifier_or_of_type_any_string_number_or_symbol); + } + } rightType = checkNonNullType(rightType, right); // TypeScript 1.0 spec (April 2014): 4.15.5 - // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, - // and the right operand to be + // The in operator requires the right operand to be // // 1. assignable to the non-primitive type, // 2. an unconstrained type parameter, @@ -31920,10 +32429,6 @@ namespace ts { // unless *all* instantiations would result in an error. // // The result is always of the Boolean primitive type. - if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) || - isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.TypeParameter))) { - error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); - } const rightTypeConstraint = getConstraintOfType(rightType); if (!allTypesAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive) || rightTypeConstraint && ( @@ -32453,7 +32958,7 @@ namespace ts { else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. - resultType = leftType === errorType || rightType === errorType ? errorType : anyType; + resultType = isErrorType(leftType) || isErrorType(rightType) ? errorType : anyType; } // Symbols are not allowed at all in arithmetic expressions @@ -32681,8 +33186,8 @@ namespace ts { let wouldWorkWithAwait = false; const errNode = errorNode || operatorToken; if (isRelated) { - const awaitedLeftType = getAwaitedType(leftType); - const awaitedRightType = getAwaitedType(rightType); + const awaitedLeftType = getAwaitedTypeNoAlias(leftType); + const awaitedRightType = getAwaitedTypeNoAlias(rightType); wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType) && !!(awaitedLeftType && awaitedRightType) && isRelated(awaitedLeftType, awaitedRightType); @@ -33283,7 +33788,7 @@ namespace ts { } function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type { - if (isJSDocTypeAssertion(node)) { + if (hasJSDocNodes(node) && isJSDocTypeAssertion(node)) { const type = getJSDocTypeAssertionType(node); return checkAssertionWorker(type, type, node.expression, checkMode); } @@ -33305,6 +33810,8 @@ namespace ts { switch (kind) { case SyntaxKind.Identifier: return checkIdentifier(node as Identifier, checkMode); + case SyntaxKind.PrivateIdentifier: + return checkPrivateIdentifierExpression(node as PrivateIdentifier); case SyntaxKind.ThisKeyword: return checkThisExpression(node); case SyntaxKind.SuperKeyword: @@ -33598,7 +34105,7 @@ namespace ts { } } - checkTypeParameters(node.typeParameters); + checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); forEach(node.parameters, checkParameter); @@ -33951,7 +34458,7 @@ namespace ts { // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. const superCallShouldBeFirst = - (compilerOptions.target !== ScriptTarget.ESNext || !useDefineForClassFields) && + (getEmitScriptTarget(compilerOptions) !== ScriptTarget.ESNext || !useDefineForClassFields) && (some((node.parent as ClassDeclaration).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) || some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier))); @@ -34070,7 +34577,7 @@ namespace ts { function getTypeParametersForTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments) { const type = getTypeFromTypeReference(node); - if (type !== errorType) { + if (!isErrorType(type)) { const symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters || @@ -34087,7 +34594,7 @@ namespace ts { } forEach(node.typeArguments, checkSourceElement); const type = getTypeFromTypeReference(node); - if (type !== errorType) { + if (!isErrorType(type)) { if (node.typeArguments && produceDiagnostics) { const typeParameters = getTypeParametersForTypeReference(node); if (typeParameters) { @@ -34727,6 +35234,11 @@ namespace ts { return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type as GenericType)[0]; } + // primitives with a `{ then() }` won't be unwrapped/adopted. + if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) { + return undefined; + } + const thenFunction = getTypeOfPropertyOfType(type, "then" as __String)!; // TODO: GH#18217 if (isTypeAny(thenFunction)) { return undefined; @@ -34759,23 +35271,92 @@ namespace ts { /** * Gets the "awaited type" of a type. * @param type The type to await. + * @param withAlias When `true`, wraps the "awaited type" in `Awaited` if needed. * @remarks The "awaited type" of an expression is its "promised type" if the expression is a * Promise-like type; otherwise, it is the type of the expression. This is used to reflect * The runtime behavior of the `await` keyword. */ - function checkAwaitedType(type: Type, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type { - const awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0); + function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type { + const awaitedType = withAlias ? + getAwaitedType(type, errorNode, diagnosticMessage, arg0) : + getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); return awaitedType || errorType; } /** - * Determines whether a type has a callable `then` member. + * Determines whether a type is an object with a callable `then` member. */ function isThenableType(type: Type): boolean { + if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) { + // primitive types cannot be considered "thenable" since they are not objects. + return false; + } + const thenFunction = getTypeOfPropertyOfType(type, "then" as __String); return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), SignatureKind.Call).length > 0; } + interface AwaitedTypeInstantiation extends Type { + _awaitedTypeBrand: never; + aliasSymbol: Symbol; + aliasTypeArguments: readonly Type[]; + } + + function isAwaitedTypeInstantiation(type: Type): type is AwaitedTypeInstantiation { + if (type.flags & TypeFlags.Conditional) { + const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ false); + return !!awaitedSymbol && type.aliasSymbol === awaitedSymbol && type.aliasTypeArguments?.length === 1; + } + return false; + } + + /** + * For a generic `Awaited`, gets `T`. + */ + function unwrapAwaitedType(type: Type) { + return type.flags & TypeFlags.Union ? mapType(type, unwrapAwaitedType) : + isAwaitedTypeInstantiation(type) ? type.aliasTypeArguments[0] : + type; + } + + function createAwaitedTypeIfNeeded(type: Type): Type { + // We wrap type `T` in `Awaited` based on the following conditions: + // - `T` is not already an `Awaited`, and + // - `T` is generic, and + // - One of the following applies: + // - `T` has no base constraint, or + // - The base constraint of `T` is `any`, `unknown`, `object`, or `{}`, or + // - The base constraint of `T` is an object type with a callable `then` method. + + if (isTypeAny(type)) { + return type; + } + + // If this is already an `Awaited`, just return it. This helps to avoid `Awaited>` in higher-order. + if (isAwaitedTypeInstantiation(type)) { + return type; + } + + // Only instantiate `Awaited` if `T` contains possibly non-primitive types. + if (isGenericObjectType(type)) { + const baseConstraint = getBaseConstraintOfType(type); + // Only instantiate `Awaited` if `T` has no base constraint, or the base constraint of `T` is `any`, `unknown`, `{}`, `object`, + // or is promise-like. + if (!baseConstraint || (baseConstraint.flags & TypeFlags.AnyOrUnknown) || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint)) { + // Nothing to do if `Awaited` doesn't exist + const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ true); + if (awaitedSymbol) { + // Unwrap unions that may contain `Awaited`, otherwise its possible to manufacture an `Awaited | U>` where + // an `Awaited` would suffice. + return getTypeAliasInstantiation(awaitedSymbol, [unwrapAwaitedType(type)]); + } + } + } + + Debug.assert(getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like."); + return type; + } + /** * Gets the "awaited type" of a type. * @@ -34787,25 +35368,35 @@ namespace ts { * This is used to reflect the runtime behavior of the `await` keyword. */ function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); + return awaitedType && createAwaitedTypeIfNeeded(awaitedType); + } + + /** + * Gets the "awaited type" of a type without introducing an `Awaited` wrapper. + * + * @see {@link getAwaitedType} + */ + function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { if (isTypeAny(type)) { return type; } + // If this is already an `Awaited`, just return it. This avoids `Awaited>` in higher-order + if (isAwaitedTypeInstantiation(type)) { + return type; + } + + // If we've already cached an awaited type, return a possible `Awaited` for it. const typeAsAwaitable = type as PromiseOrAwaitableType; if (typeAsAwaitable.awaitedTypeOfType) { return typeAsAwaitable.awaitedTypeOfType; } // For a union, get a union of the awaited types of each constituent. - // - return typeAsAwaitable.awaitedTypeOfType = - mapType(type, errorNode ? constituentType => getAwaitedTypeWorker(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeWorker); - } - - function getAwaitedTypeWorker(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { - const typeAsAwaitable = type as PromiseOrAwaitableType; - if (typeAsAwaitable.awaitedTypeOfType) { - return typeAsAwaitable.awaitedTypeOfType; + if (type.flags & TypeFlags.Union) { + const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias; + return typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper); } const promisedType = getPromisedTypeOfPromise(type); @@ -34853,7 +35444,7 @@ namespace ts { // Keep track of the type we're about to unwrap to avoid bad recursive promise types. // See the comments above for more information. awaitedTypeStack.push(type.id); - const awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0); + const awaitedType = getAwaitedTypeNoAlias(promisedType, errorNode, diagnosticMessage, arg0); awaitedTypeStack.pop(); if (!awaitedType) { @@ -34880,7 +35471,7 @@ namespace ts { // be treated as a promise, they can cast to . if (isThenableType(type)) { if (errorNode) { - if (!diagnosticMessage) return Debug.fail(); + Debug.assertIsDefined(diagnosticMessage); error(errorNode, diagnosticMessage, arg0); } return undefined; @@ -34929,14 +35520,14 @@ namespace ts { const returnType = getTypeFromTypeNode(returnTypeNode); if (languageVersion >= ScriptTarget.ES2015) { - if (returnType === errorType) { + if (isErrorType(returnType)) { return; } const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. - error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedType(returnType) || voidType)); + error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedTypeNoAlias(returnType) || voidType)); return; } } @@ -34944,7 +35535,7 @@ namespace ts { // Always mark the type node as referenced if it points to a value markTypeNodeAsReferenced(returnTypeNode); - if (returnType === errorType) { + if (isErrorType(returnType)) { return; } @@ -34956,7 +35547,7 @@ namespace ts { const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, SymbolFlags.Value, /*ignoreErrors*/ true); const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType; - if (promiseConstructorType === errorType) { + if (isErrorType(promiseConstructorType)) { if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } @@ -34989,7 +35580,7 @@ namespace ts { return; } } - checkAwaitedType(returnType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + checkAwaitedType(returnType, /*withAlias*/ false, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } /** Check a decorator */ @@ -35231,6 +35822,7 @@ namespace ts { checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); } checkSourceElement(node.typeExpression); + checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); } function checkJSDocTemplateTag(node: JSDocTemplateTag): void { @@ -35321,6 +35913,13 @@ namespace ts { } } + function checkJSDocAccessibilityModifiers(node: JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag): void { + const host = getJSDocHost(node); + if (host && isPrivateIdentifierClassElementDeclaration(host)) { + error(node, Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier); + } + } + function getIdentifierFromEntityNameExpression(node: Identifier | PropertyAccessExpression): Identifier | PrivateIdentifier; function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined; function getIdentifierFromEntityNameExpression(node: Expression): Identifier | PrivateIdentifier | undefined { @@ -35817,7 +36416,7 @@ namespace ts { function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier | undefined) { // No need to check for require or exports for ES6 modules and later - if (moduleKind >= ModuleKind.ES2015) { + if (moduleKind >= ModuleKind.ES2015 && !(moduleKind >= ModuleKind.Node12 && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { return; } @@ -36128,7 +36727,7 @@ namespace ts { // initializer is consistent with type associated with the node const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node)); - if (type !== errorType && declarationType !== errorType && + if (!isErrorType(type) && !isErrorType(declarationType) && !isTypeIdenticalTo(type, declarationType) && !(symbol.flags & SymbolFlags.Assignment)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType); @@ -36807,6 +37406,10 @@ namespace ts { if (iterationTypes === noIterationTypes) return noIterationTypes; if (iterationTypes === anyIterationTypes) return anyIterationTypes; const { yieldType, returnType, nextType } = iterationTypes; + // if we're requesting diagnostics, report errors for a missing `Awaited`. + if (errorNode) { + getGlobalAwaitedSymbol(/*reportErrors*/ true); + } return createIterationTypes( getAwaitedType(yieldType, errorNode) || anyType, getAwaitedType(returnType, errorNode) || anyType, @@ -36833,7 +37436,9 @@ namespace ts { getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) || getIterationTypesOfIterableFast(type, asyncIterationTypesResolver); if (iterationTypes) { - return iterationTypes; + return use & IterationUse.ForOfFlag ? + getAsyncFromSyncIterationTypes(iterationTypes, errorNode) : + iterationTypes; } } @@ -36922,7 +37527,7 @@ namespace ts { // While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use // different definitions. const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver); - return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType)); + return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || yieldType, resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || returnType, nextType)); } // As an optimization, if the type is an instantiation of the following global type, then @@ -36930,7 +37535,7 @@ namespace ts { // - `Generator` or `AsyncGenerator` if (isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) { const [yieldType, returnType, nextType] = getTypeArguments(type as GenericType); - return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType)); + return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || yieldType, resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || returnType, nextType)); } } @@ -37262,8 +37867,8 @@ namespace ts { function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) { const isGenerator = !!(functionFlags & FunctionFlags.Generator); const isAsync = !!(functionFlags & FunctionFlags.Async); - return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ?? errorType : - isAsync ? getAwaitedType(returnType) ?? errorType : + return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) || errorType : + isAsync ? getAwaitedTypeNoAlias(returnType) || errorType : returnType; } @@ -37307,7 +37912,7 @@ namespace ts { else if (getReturnTypeFromAnnotation(container)) { const unwrappedReturnType = unwrapReturnType(returnType, functionFlags) ?? returnType; const unwrappedExprType = functionFlags & FunctionFlags.Async - ? checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) + ? checkAwaitedType(exprType, /*withAlias*/ false, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) : exprType; if (unwrappedReturnType) { // If the function has a return type, but promisedType is @@ -37555,8 +38160,8 @@ namespace ts { * The name cannot be used as 'Object' of user defined types with special target. */ function checkClassNameCollisionWithObject(name: Identifier): void { - if (languageVersion === ScriptTarget.ES5 && name.escapedText === "Object" - && moduleKind < ModuleKind.ES2015) { + if (languageVersion >= ScriptTarget.ES5 && name.escapedText === "Object" + && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(name).impliedNodeFormat === ModuleKind.CommonJS)) { error(name, Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494 } } @@ -37793,7 +38398,7 @@ namespace ts { checkTypeReferenceNode(typeRefNode); if (produceDiagnostics) { const t = getReducedType(getTypeFromTypeNode(typeRefNode)); - if (t !== errorType) { + if (!isErrorType(t)) { if (isValidBaseType(t)) { const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ? Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : @@ -37919,6 +38524,7 @@ namespace ts { memberName: string, errorNode?: Node, ): MemberOverrideDiagnostic { + const isJs = isInJSFile(node); const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); if (baseWithThis && (memberHasOverrideModifier || compilerOptions.noImplicitOverride)) { const memberEscapedName = escapeLeadingUnderscores(memberName); @@ -37932,8 +38538,19 @@ namespace ts { if (errorNode) { const suggestion = getSuggestedSymbolForNonexistentClassMember(memberName, baseType); // Again, using symbol name: note that's different from `symbol.escapedName` suggestion ? - error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) : - error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName); + error( + errorNode, + isJs ? + Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 : + Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, + baseClassName, + symbolToString(suggestion)) : + error( + errorNode, + isJs ? + Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0 : + Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, + baseClassName); } return MemberOverrideDiagnostic.HasInvalidOverride; } @@ -37946,8 +38563,12 @@ namespace ts { if (!baseHasAbstract) { if (errorNode) { const diag = memberIsParameterProperty ? - Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 : - Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0; + isJs ? + Diagnostics.This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : + Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 : + isJs ? + Diagnostics.This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 : + Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0; error(errorNode, diag, baseClassName); } return MemberOverrideDiagnostic.NeedsOverride; @@ -37963,7 +38584,12 @@ namespace ts { else if (memberHasOverrideModifier) { if (errorNode) { const className = typeToString(type); - error(errorNode, Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, className); + error( + errorNode, + isJs ? + Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class : + Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, + className); } return MemberOverrideDiagnostic.HasInvalidOverride; } @@ -38873,13 +39499,49 @@ namespace ts { error(node, message, symbolToString(symbol)); } - // Don't allow to re-export something with no value side when `--isolatedModules` is set. if (compilerOptions.isolatedModules - && node.kind === SyntaxKind.ExportSpecifier - && !node.parent.parent.isTypeOnly - && !(target.flags & SymbolFlags.Value) + && !isTypeOnlyImportOrExportDeclaration(node) && !(node.flags & NodeFlags.Ambient)) { - error(node, Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type); + const typeOnlyAlias = getTypeOnlyAliasDeclaration(symbol); + const isType = !(target.flags & SymbolFlags.Value); + if (isType || typeOnlyAlias) { + switch (node.kind) { + case SyntaxKind.ImportClause: + case SyntaxKind.ImportSpecifier: + case SyntaxKind.ImportEqualsDeclaration: { + if (compilerOptions.preserveValueImports) { + Debug.assertIsDefined(node.name, "An ImportClause with a symbol should have a name"); + const message = isType + ? Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled + : Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_preserveValueImports_and_isolatedModules_are_both_enabled; + const name = idText(node.kind === SyntaxKind.ImportSpecifier ? node.propertyName || node.name : node.name); + addTypeOnlyDeclarationRelatedInfo( + error(node, message, name), + isType ? undefined : typeOnlyAlias, + name + ); + } + break; + } + case SyntaxKind.ExportSpecifier: { + // Don't allow re-exporting an export that will be elided when `--isolatedModules` is set. + // The exception is that `import type { A } from './a'; export { A }` is allowed + // because single-file analysis can determine that the export should be dropped. + if (getSourceFileOfNode(typeOnlyAlias) !== getSourceFileOfNode(node)) { + const message = isType + ? Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type + : Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_isolatedModules_is_enabled; + const name = idText(node.propertyName || node.name); + addTypeOnlyDeclarationRelatedInfo( + error(node, message, name), + isType ? undefined : typeOnlyAlias, + name + ); + return; + } + } + } + } } if (isImportSpecifier(node) && target.declarations?.every(d => !!(getCombinedNodeFlags(d) & NodeFlags.Deprecated))) { @@ -38893,12 +39555,24 @@ namespace ts { checkAliasSymbol(node); if (node.kind === SyntaxKind.ImportSpecifier && idText(node.propertyName || node.name) === "default" && - compilerOptions.esModuleInterop && - moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) { + getESModuleInterop(compilerOptions) && + moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); } } + function checkAssertClause(declaration: ImportDeclaration | ExportDeclaration) { + if (declaration.assertClause) { + if (moduleKind !== ModuleKind.ESNext) { + return grammarErrorOnNode(declaration.assertClause, Diagnostics.Import_assertions_are_only_supported_when_the_module_option_is_set_to_esnext); + } + + if (isImportDeclaration(declaration) ? declaration.importClause?.isTypeOnly : declaration.isTypeOnly) { + return grammarErrorOnNode(declaration.assertClause, Diagnostics.Import_assertions_cannot_be_used_with_type_only_imports_or_exports); + } + } + } + function checkImportDeclaration(node: ImportDeclaration) { if (checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. @@ -38916,7 +39590,7 @@ namespace ts { if (importClause.namedBindings) { if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { checkImportBinding(importClause.namedBindings); - if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015 && compilerOptions.esModuleInterop) { + if (moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && getESModuleInterop(compilerOptions)) { // import * as ns from "foo"; checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); } @@ -38930,7 +39604,7 @@ namespace ts { } } } - + checkAssertClause(node); } function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { @@ -38964,7 +39638,7 @@ namespace ts { } } else { - if (moduleKind >= ModuleKind.ES2015 && !node.isTypeOnly && !(node.flags & NodeFlags.Ambient)) { + if (moduleKind >= ModuleKind.ES2015 && getSourceFileOfNode(node).impliedNodeFormat === undefined && !node.isTypeOnly && !(node.flags & NodeFlags.Ambient)) { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } @@ -39009,12 +39683,12 @@ namespace ts { else if (node.exportClause) { checkAliasSymbol(node.exportClause); } - if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) { + if (moduleKind !== ModuleKind.System && (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) { if (node.exportClause) { // export * as ns from "foo"; // For ES2015 modules, we emit it as a pair of `import * as a_1 ...; export { a_1 as ns }` and don't need the helper. // We only use the helper here when in esModuleInterop - if (compilerOptions.esModuleInterop) { + if (getESModuleInterop(compilerOptions)) { checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportStar); } } @@ -39025,14 +39699,19 @@ namespace ts { } } } + checkAssertClause(node); } function checkGrammarExportDeclaration(node: ExportDeclaration): boolean { - const isTypeOnlyExportStar = node.isTypeOnly && node.exportClause?.kind !== SyntaxKind.NamedExports; - if (isTypeOnlyExportStar) { - grammarErrorOnNode(node, Diagnostics.Only_named_exports_may_use_export_type); + if (node.isTypeOnly) { + if (node.exportClause?.kind === SyntaxKind.NamedExports) { + return checkGrammarNamedImportsOrExports(node.exportClause); + } + else { + return grammarErrorOnNode(node, Diagnostics.Only_named_exports_may_use_export_type); + } } - return !isTypeOnlyExportStar; + return false; } function checkGrammarModuleElementContext(node: Statement, errorMessage: DiagnosticMessage): boolean { @@ -39105,9 +39784,9 @@ namespace ts { } } else { - if (compilerOptions.esModuleInterop && + if (getESModuleInterop(compilerOptions) && moduleKind !== ModuleKind.System && - moduleKind < ModuleKind.ES2015 && + (moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && idText(node.propertyName || node.name) === "default") { checkExternalEmitHelpers(node, ExternalEmitHelpers.ImportDefault); } @@ -39175,7 +39854,7 @@ namespace ts { } if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) { - if (moduleKind >= ModuleKind.ES2015) { + if (moduleKind >= ModuleKind.ES2015 && getSourceFileOfNode(node).impliedNodeFormat !== ModuleKind.CommonJS) { // export assignment is not supported in es6 modules grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); } @@ -39361,6 +40040,10 @@ namespace ts { return; case SyntaxKind.JSDocTypeExpression: return checkSourceElement((node as JSDocTypeExpression).type); + case SyntaxKind.JSDocPublicTag: + case SyntaxKind.JSDocProtectedTag: + case SyntaxKind.JSDocPrivateTag: + return checkJSDocAccessibilityModifiers(node as JSDocPublicTag | JSDocProtectedTag | JSDocPrivateTag); case SyntaxKind.IndexedAccessType: return checkIndexedAccessType(node as IndexedAccessTypeNode); case SyntaxKind.MappedType: @@ -40050,6 +40733,9 @@ namespace ts { } return result; } + else if (isPrivateIdentifier(name)) { + return getSymbolForPrivateIdentifierExpression(name); + } else if (name.kind === SyntaxKind.PropertyAccessExpression || name.kind === SyntaxKind.QualifiedName) { const links = getNodeLinks(name); if (links.resolvedSymbol) { @@ -40073,7 +40759,8 @@ namespace ts { } else if (isTypeReferenceIdentifier(name as EntityName)) { const meaning = name.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace; - return resolveEntityName(name as EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); + const symbol = resolveEntityName(name as EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); + return symbol && symbol !== unknownSymbol ? symbol : getUnresolvedSymbolForEntityName(name as EntityName); } if (name.parent.kind === SyntaxKind.TypePredicate) { return resolveEntityName(name as Identifier, /*meaning*/ SymbolFlags.FunctionScopedVariable); @@ -40333,7 +41020,7 @@ namespace ts { const symbol = getSymbolAtLocation(node); if (symbol) { const declaredType = getDeclaredTypeOfSymbol(symbol); - return declaredType !== errorType ? declaredType : getTypeOfSymbol(symbol); + return !isErrorType(declaredType) ? declaredType : getTypeOfSymbol(symbol); } } @@ -40660,13 +41347,13 @@ namespace ts { function isValueAliasDeclaration(node: Node): boolean { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: - return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol); + return isAliasResolvedToValue(getSymbolOfNode(node)); case SyntaxKind.ImportClause: case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - const symbol = getSymbolOfNode(node) || unknownSymbol; - return isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol); + const symbol = getSymbolOfNode(node); + return !!symbol && isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol); case SyntaxKind.ExportDeclaration: const exportClause = (node as ExportDeclaration).exportClause; return !!exportClause && ( @@ -40675,7 +41362,7 @@ namespace ts { ); case SyntaxKind.ExportAssignment: return (node as ExportAssignment).expression && (node as ExportAssignment).expression.kind === SyntaxKind.Identifier ? - isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) : + isAliasResolvedToValue(getSymbolOfNode(node)) : true; } return false; @@ -40692,7 +41379,10 @@ namespace ts { return isValue && node.moduleReference && !nodeIsMissing(node.moduleReference); } - function isAliasResolvedToValue(symbol: Symbol): boolean { + function isAliasResolvedToValue(symbol: Symbol | undefined): boolean { + if (!symbol) { + return false; + } const target = resolveAlias(symbol); if (target === unknownSymbol) { return true; @@ -40874,7 +41564,7 @@ namespace ts { return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; } const type = getDeclaredTypeOfSymbol(typeSymbol); - if (type === errorType) { + if (isErrorType(type)) { return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown; } else if (type.flags & TypeFlags.AnyOrUnknown) { @@ -41462,6 +42152,7 @@ namespace ts { case ExternalEmitHelpers.MakeTemplateObject: return "__makeTemplateObject"; case ExternalEmitHelpers.ClassPrivateFieldGet: return "__classPrivateFieldGet"; case ExternalEmitHelpers.ClassPrivateFieldSet: return "__classPrivateFieldSet"; + case ExternalEmitHelpers.ClassPrivateFieldIn: return "__classPrivateFieldIn"; case ExternalEmitHelpers.CreateBinding: return "__createBinding"; default: return Debug.fail("Unrecognized helper"); } @@ -41928,6 +42619,12 @@ namespace ts { return false; } + if (node.typeParameters && !(length(node.typeParameters) > 1 || node.typeParameters.hasTrailingComma || node.typeParameters[0].constraint)) { + if (file && fileExtensionIsOneOf(file.fileName, [Extension.Mts, Extension.Cts])) { + grammarErrorOnNode(node.typeParameters[0], Diagnostics.This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_constraint); + } + } + const { equalsGreaterThanToken } = node; const startLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line; const endLine = getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line; @@ -42298,9 +42995,9 @@ namespace ts { diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module)); } - if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || languageVersion < ScriptTarget.ES2017) { + if ((moduleKind !== ModuleKind.ES2022 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System && !(moduleKind === ModuleKind.NodeNext && getSourceFileOfNode(forInOrOfStatement).impliedNodeFormat === ModuleKind.ESNext)) || languageVersion < ScriptTarget.ES2017) { diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier, - Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher)); + Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher)); } } } @@ -42679,8 +43376,7 @@ namespace ts { return grammarErrorOnNode(node.exclamationToken, message); } - const moduleKind = getEmitModuleKind(compilerOptions); - if (moduleKind < ModuleKind.ES2015 && moduleKind !== ModuleKind.System && + if ((moduleKind < ModuleKind.ES2015 || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS) && moduleKind !== ModuleKind.System && !(node.parent.parent.flags & NodeFlags.Ambient) && hasSyntacticModifier(node.parent.parent, ModifierFlags.Export)) { checkESModuleMarker(node.name); } @@ -43045,12 +43741,27 @@ namespace ts { if (node.isTypeOnly && node.name && node.namedBindings) { return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both); } + if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { + return checkGrammarNamedImportsOrExports(node.namedBindings); + } return false; } + function checkGrammarNamedImportsOrExports(namedBindings: NamedImportsOrExports): boolean { + return !!forEach(namedBindings.elements, specifier => { + if (specifier.isTypeOnly) { + return grammarErrorOnFirstToken( + specifier, + specifier.kind === SyntaxKind.ImportSpecifier + ? Diagnostics.The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement + : Diagnostics.The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement); + } + }); + } + function checkGrammarImportCallExpression(node: ImportCall): boolean { if (moduleKind === ModuleKind.ES2015) { - return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system_or_umd); + return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node12_or_nodenext); } if (node.typeArguments) { @@ -43058,14 +43769,25 @@ namespace ts { } const nodeArguments = node.arguments; - if (nodeArguments.length !== 1) { - return grammarErrorOnNode(node, Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument); + if (moduleKind !== ModuleKind.ESNext) { + // We are allowed trailing comma after proposal-import-assertions. + checkGrammarForDisallowedTrailingComma(nodeArguments); + + if (nodeArguments.length > 1) { + const assertionArgument = nodeArguments[1]; + return grammarErrorOnNode(assertionArgument, Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext); + } } - checkGrammarForDisallowedTrailingComma(nodeArguments); + + if (nodeArguments.length === 0 || nodeArguments.length > 2) { + return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_assertion_as_arguments); + } + // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import. // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import. - if (isSpreadElement(nodeArguments[0])) { - return grammarErrorOnNode(nodeArguments[0], Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element); + const spreadElement = find(nodeArguments, isSpreadElement); + if (spreadElement) { + return grammarErrorOnNode(spreadElement, Diagnostics.Argument_of_dynamic_import_cannot_be_spread_element); } return false; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 05d80d97ccc6e..03a452296b741 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -71,6 +71,7 @@ namespace ts { ["es2021.promise", "lib.es2021.promise.d.ts"], ["es2021.string", "lib.es2021.string.d.ts"], ["es2021.weakref", "lib.es2021.weakref.d.ts"], + ["es2021.intl", "lib.es2021.intl.d.ts"], ["esnext.array", "lib.es2019.array.d.ts"], ["esnext.symbol", "lib.es2019.symbol.d.ts"], ["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"], @@ -393,7 +394,10 @@ namespace ts { es6: ModuleKind.ES2015, es2015: ModuleKind.ES2015, es2020: ModuleKind.ES2020, - esnext: ModuleKind.ESNext + es2022: ModuleKind.ES2022, + esnext: ModuleKind.ESNext, + node12: ModuleKind.Node12, + nodenext: ModuleKind.NodeNext, })), affectsModuleResolution: true, affectsEmit: true, @@ -570,7 +574,7 @@ namespace ts { type: new Map(getEntries({ remove: ImportsNotUsedAsValues.Remove, preserve: ImportsNotUsedAsValues.Preserve, - error: ImportsNotUsedAsValues.Error + error: ImportsNotUsedAsValues.Error, })), affectsEmit: true, affectsSemanticDiagnostics: true, @@ -1168,6 +1172,14 @@ namespace ts { description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields, defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext }, + { + name: "preserveValueImports", + type: "boolean", + affectsEmit: true, + category: Diagnostics.Emit, + description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed, + }, + { name: "keyofStringsOnly", type: "boolean", @@ -1328,7 +1340,7 @@ namespace ts { /* @internal */ export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, - target: ScriptTarget.ES5, + target: ScriptTarget.ES2016, strict: true, esModuleInterop: true, forceConsistentCasingInFileNames: true, @@ -2339,6 +2351,47 @@ namespace ts { return result; } + /** + * Generate a list of the compiler options whose value is not the default. + * @param options compilerOptions to be evaluated. + /** @internal */ + export function getCompilerOptionsDiffValue(options: CompilerOptions, newLine: string): string { + const compilerOptionsMap = getSerializedCompilerOption(options); + return getOverwrittenDefaultOptions(); + + function makePadding(paddingLength: number): string { + return Array(paddingLength + 1).join(" "); + } + + function getOverwrittenDefaultOptions() { + const result: string[] = []; + const tab = makePadding(2); + commandOptionsWithoutBuild.forEach(cmd => { + if (!compilerOptionsMap.has(cmd.name)) { + return; + } + + const newValue = compilerOptionsMap.get(cmd.name); + const defaultValue = getDefaultValueForOption(cmd); + if (newValue !== defaultValue) { + result.push(`${tab}${cmd.name}: ${newValue}`); + } + else if (hasProperty(defaultInitCompilerOptions, cmd.name)) { + result.push(`${tab}${cmd.name}: ${defaultValue}`); + } + }); + return result.join(newLine) + newLine; + } + } + + /** + * Get the compiler options to be written into the tsconfig.json. + * @param options commandlineOptions to be included in the compileOptions. + */ + function getSerializedCompilerOption(options: CompilerOptions): ESMap { + const compilerOptions = extend(options, defaultInitCompilerOptions); + return serializeCompilerOptions(compilerOptions); + } /** * Generate tsconfig configuration when running command line "--init" * @param options commandlineOptions to be generated into tsconfig.json @@ -2346,29 +2399,9 @@ namespace ts { */ /* @internal */ export function generateTSConfig(options: CompilerOptions, fileNames: readonly string[], newLine: string): string { - const compilerOptions = extend(options, defaultInitCompilerOptions); - const compilerOptionsMap = serializeCompilerOptions(compilerOptions); + const compilerOptionsMap = getSerializedCompilerOption(options); return writeConfigurations(); - function getDefaultValueForOption(option: CommandLineOption) { - switch (option.type) { - case "number": - return 1; - case "boolean": - return true; - case "string": - return option.isFilePath ? "./" : ""; - case "list": - return []; - case "object": - return {}; - default: - const iterResult = option.type.keys().next(); - if (!iterResult.done) return iterResult.value; - return Debug.fail("Expected 'option.type' to have entries."); - } - } - function makePadding(paddingLength: number): string { return Array(paddingLength + 1).join(" "); } @@ -2852,6 +2885,7 @@ namespace ts { let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined; let watchOptions: WatchOptions | undefined; let extendedConfigPath: string | undefined; + let rootCompilerOptions: PropertyName[] | undefined; const optionsIterator: JsonConversionNotifier = { onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) { @@ -2894,6 +2928,9 @@ namespace ts { if (key === "excludes") { errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); } + if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) { + rootCompilerOptions = append(rootCompilerOptions, keyNode); + } } }; const json = convertConfigFileToObject(sourceFile, errors, /*reportOptionsErrors*/ true, optionsIterator); @@ -2913,6 +2950,10 @@ namespace ts { } } + if (rootCompilerOptions && json && json.compilerOptions === undefined) { + errors.push(createDiagnosticForNodeInSourceFile(sourceFile, rootCompilerOptions[0], Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, getTextOfPropertyName(rootCompilerOptions[0]) as string)); + } + return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath }; } @@ -3199,7 +3240,7 @@ namespace ts { // Rather than re-query this for each file and filespec, we query the supported extensions // once and store it on the expansion context. const supportedExtensions = getSupportedExtensions(options, extraFileExtensions); - const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); + const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Literal files are always included verbatim. An "include" or "exclude" specification cannot // remove a literal file. @@ -3212,7 +3253,7 @@ namespace ts { let jsonOnlyIncludeRegexes: readonly RegExp[] | undefined; if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) { - for (const file of host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { + for (const file of host.readDirectory(basePath, flatten(supportedExtensionsWithJsonIfResolveJsonModule), validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) { if (fileExtensionIs(file, Extension.Json)) { // Valid only if *.json specified if (!jsonOnlyIncludeRegexes) { @@ -3437,16 +3478,24 @@ namespace ts { * extension priority. * * @param file The path to the file. - * @param extensionPriority The priority of the extension. - * @param context The expansion context. */ - function hasFileWithHigherPriorityExtension(file: string, literalFiles: ESMap, wildcardFiles: ESMap, extensions: readonly string[], keyMapper: (value: string) => string) { - const extensionPriority = getExtensionPriority(file, extensions); - const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority, extensions); - for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) { - const higherPriorityExtension = extensions[i]; - const higherPriorityPath = keyMapper(changeExtension(file, higherPriorityExtension)); + function hasFileWithHigherPriorityExtension(file: string, literalFiles: ESMap, wildcardFiles: ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { + const extensionGroup = forEach(extensions, group => fileExtensionIsOneOf(file, group) ? group : undefined); + if (!extensionGroup) { + return false; + } + for (const ext of extensionGroup) { + if (fileExtensionIs(file, ext)) { + return false; + } + const higherPriorityPath = keyMapper(changeExtension(file, ext)); if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) { + if (ext === Extension.Dts && (fileExtensionIs(file, Extension.Js) || fileExtensionIs(file, Extension.Jsx))) { + // LEGACY BEHAVIOR: An off-by-one bug somewhere in the extension priority system for wildcard module loading allowed declaration + // files to be loaded alongside their js(x) counterparts. We regard this as generally undesirable, but retain the behavior to + // prevent breakage. + continue; + } return true; } } @@ -3459,15 +3508,18 @@ namespace ts { * already been included. * * @param file The path to the file. - * @param extensionPriority The priority of the extension. - * @param context The expansion context. */ - function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: ESMap, extensions: readonly string[], keyMapper: (value: string) => string) { - const extensionPriority = getExtensionPriority(file, extensions); - const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority, extensions); - for (let i = nextExtensionPriority; i < extensions.length; i++) { - const lowerPriorityExtension = extensions[i]; - const lowerPriorityPath = keyMapper(changeExtension(file, lowerPriorityExtension)); + function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: ESMap, extensions: readonly string[][], keyMapper: (value: string) => string) { + const extensionGroup = forEach(extensions, group => fileExtensionIsOneOf(file, group) ? group : undefined); + if (!extensionGroup) { + return; + } + for (let i = extensionGroup.length - 1; i >= 0; i--) { + const ext = extensionGroup[i]; + if (fileExtensionIs(file, ext)) { + return; + } + const lowerPriorityPath = keyMapper(changeExtension(file, ext)); wildcardFiles.delete(lowerPriorityPath); } } @@ -3511,4 +3563,24 @@ namespace ts { })!; // TODO: GH#18217 } } + + + function getDefaultValueForOption(option: CommandLineOption) { + switch (option.type) { + case "number": + return 1; + case "boolean": + return true; + case "string": + return option.isFilePath ? "./" : ""; + case "list": + return []; + case "object": + return {}; + default: + const iterResult = option.type.keys().next(); + if (!iterResult.done) return iterResult.value; + return Debug.fail("Expected 'option.type' to have entries."); + } + } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d1a03c6a31e9f..e9ae0131b05e6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -920,15 +920,15 @@ "category": "Error", "code": 1322 }, - "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'esnext', 'commonjs', 'amd', 'system', or 'umd'.": { + "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node12', or 'nodenext'.": { "category": "Error", "code": 1323 }, - "Dynamic import must have one specifier as an argument.": { + "Dynamic imports only support a second argument when the '--module' option is set to 'esnext'.": { "category": "Error", "code": 1324 }, - "Specifier of dynamic import cannot be spread element.": { + "Argument of dynamic import cannot be spread element.": { "category": "Error", "code": 1325 }, @@ -992,7 +992,7 @@ "category": "Error", "code": 1342 }, - "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'.": { + "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node12', or 'nodenext'.": { "category": "Error", "code": 1343 }, @@ -1116,7 +1116,7 @@ "category": "Message", "code": 1377 }, - "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.": { + "Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": { "category": "Error", "code": 1378 }, @@ -1324,7 +1324,7 @@ "category": "Error", "code": 1431 }, - "Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.": { + "Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": { "category": "Error", "code": 1432 }, @@ -1372,6 +1372,39 @@ "category": "Error", "code": 1443 }, + "'{0}' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": { + "category": "Error", + "code": 1444 + }, + "'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": { + "category": "Error", + "code": 1446 + }, + "'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 1448 + }, + "Preserve unused imported values in the JavaScript output that would otherwise be removed.": { + "category": "Message", + "code": 1449 + }, + "Dynamic imports can only accept a module specifier and an optional assertion as arguments": { + "category": "Message", + "code": 1450 + }, + "Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression": { + "category": "Error", + "code": 1451 + }, + + "The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": { + "category": "Error", + "code": 1470 + }, + "Module '{0}' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.": { + "category": "Error", + "code": 1471 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", @@ -1401,6 +1434,14 @@ "code": 2205, "elidedInCompatabilityPyramid": true }, + "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.": { + "category": "Error", + "code": 2206 + }, + "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.": { + "category": "Error", + "code": 2207 + }, "Duplicate identifier '{0}'.": { "category": "Error", @@ -1634,7 +1675,7 @@ "category": "Error", "code": 2359 }, - "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.": { + "The left-hand side of an 'in' expression must be a private identifier or of type 'any', 'string', 'number', or 'symbol'.": { "category": "Error", "code": 2360 }, @@ -3284,6 +3325,22 @@ "category": "Error", "code": 2819 }, + "Type '{0}' is not assignable to type '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 2820 + }, + "Import assertions are only supported when the '--module' option is set to 'esnext'.": { + "category": "Error", + "code": 2821 + }, + "Import assertions cannot be used with type-only imports or exports.": { + "category": "Error", + "code": 2822 + }, + "Cannot find namespace '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 2833 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", @@ -3689,7 +3746,26 @@ "category": "Error", "code": 4118 }, - + "This member must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { + "category": "Error", + "code": 4119 + }, + "This parameter property must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { + "category": "Error", + "code": 4120 + }, + "This member cannot have a JSDoc comment with an '@override' tag because its containing class '{0}' does not extend another class.": { + "category": "Error", + "code": 4121 + }, + "This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class '{0}'.": { + "category": "Error", + "code": 4122 + }, + "This member cannot have a JSDoc comment with an 'override' tag because it is not declared in the base class '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 4123 + }, "The current host does not support the '{0}' option.": { "category": "Error", "code": 5001 @@ -3910,6 +3986,10 @@ "category": "Error", "code": 5094 }, + "Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.": { + "category": "Error", + "code": 5095 + }, "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", @@ -3923,10 +4003,6 @@ "category": "Message", "code": 6002 }, - "Specify the location where debugger should locate map files instead of generated locations.": { - "category": "Message", - "code": 6003 - }, "Specify the location where debugger should locate TypeScript files instead of source locations.": { "category": "Message", "code": 6004 @@ -4493,10 +4569,6 @@ "category": "Message", "code": 6163 }, - "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": { - "category": "Message", - "code": 6164 - }, "Do not truncate error messages.": { "category": "Message", "code": 6165 @@ -4834,6 +4906,39 @@ "category": "Message", "code": 6257 }, + "'{0}' should be set inside the 'compilerOptions' object of the config json file": { + "category": "Error", + "code": 6258 + }, + + "Directory '{0}' has no containing package.json scope. Imports will not resolve.": { + "category": "Message", + "code": 6270 + }, + "Import specifier '{0}' does not exist in package.json scope at path '{1}'.": { + "category": "Message", + "code": 6271 + }, + "Invalid import specifier '{0}' has no possible resolutions.": { + "category": "Message", + "code": 6272 + }, + "package.json scope '{0}' has no imports defined.": { + "category": "Message", + "code": 6273 + }, + "package.json scope '{0}' explicitly maps specifier '{1}' to null.": { + "category": "Message", + "code": 6274 + }, + "package.json scope '{0}' has invalid type for target of specifier '{1}'": { + "category": "Message", + "code": 6275 + }, + "Export specifier '{0}' does not exist in package.json scope at path '{1}'.": { + "category": "Message", + "code": 6276 + }, "Enable project compilation": { "category": "Message", @@ -5880,6 +5985,14 @@ "category": "Error", "code": 7058 }, + "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.": { + "category": "Error", + "code": 7059 + }, + "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma or explicit constraint.": { + "category": "Error", + "code": 7060 + }, "You cannot rename this element.": { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e873e0919577a..996cbfcca5c4b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -89,7 +89,7 @@ namespace ts { return getOutputPathsForBundle(options, forceDtsPaths); } else { - const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options)); + const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile.fileName, options)); const isJsonFile = isJsonSourceFile(sourceFile); // If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it const isJsonEmittedToSameLocation = isJsonFile && @@ -106,27 +106,13 @@ namespace ts { return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined; } - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. - // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. - // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve /* @internal */ - export function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension { - if (isJsonSourceFile(sourceFile)) { - return Extension.Json; - } - - if (options.jsx === JsxEmit.Preserve) { - if (isSourceFileJS(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) { - return Extension.Jsx; - } - } - else if (sourceFile.languageVariant === LanguageVariant.JSX) { - // TypeScript source file preserving JSX syntax - return Extension.Jsx; - } - } - return Extension.Js; + export function getOutputExtension(fileName: string, options: CompilerOptions): Extension { + return fileExtensionIs(fileName, Extension.Json) ? Extension.Json : + options.jsx === JsxEmit.Preserve && fileExtensionIsOneOf(fileName, [Extension.Jsx, Extension.Tsx]) ? Extension.Jsx : + fileExtensionIsOneOf(fileName, [Extension.Mts, Extension.Mjs]) ? Extension.Mjs : + fileExtensionIsOneOf(fileName, [Extension.Cts, Extension.Cjs]) ? Extension.Cjs : + Extension.Js; } function getOutputPathWithoutChangingExt(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, outputDir: string | undefined, getCommonSourceDirectory?: () => string) { @@ -140,10 +126,9 @@ namespace ts { /* @internal */ export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory?: () => string) { - Debug.assert(!fileExtensionIs(inputFileName, Extension.Dts) && !fileExtensionIs(inputFileName, Extension.Json)); return changeExtension( getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir, getCommonSourceDirectory), - Extension.Dts + getDeclarationEmitExtensionForPath(inputFileName) ); } @@ -152,11 +137,7 @@ namespace ts { const isJsonFile = fileExtensionIs(inputFileName, Extension.Json); const outputFileName = changeExtension( getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir, getCommonSourceDirectory), - isJsonFile ? - Extension.Json : - configFile.options.jsx === JsxEmit.Preserve && (fileExtensionIs(inputFileName, Extension.Tsx) || fileExtensionIs(inputFileName, Extension.Jsx)) ? - Extension.Jsx : - Extension.Js + getOutputExtension(inputFileName, configFile.options) ); return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== Comparison.EqualTo ? outputFileName : @@ -238,7 +219,7 @@ namespace ts { export function getCommonSourceDirectoryOfConfig({ options, fileNames }: ParsedCommandLine, ignoreCase: boolean): string { return getCommonSourceDirectory( options, - () => filter(fileNames, file => !(options.noEmitForJsFiles && fileExtensionIsOneOf(file, supportedJSExtensions)) && !fileExtensionIs(file, Extension.Dts)), + () => filter(fileNames, file => !(options.noEmitForJsFiles && fileExtensionIsOneOf(file, supportedJSExtensionsFlat)) && !fileExtensionIs(file, Extension.Dts)), getDirectoryPath(normalizeSlashes(Debug.checkDefined(options.configFilePath))), createGetCanonicalFileName(!ignoreCase) ); @@ -1521,6 +1502,10 @@ namespace ts { return emitNamedExports(node as NamedExports); case SyntaxKind.ExportSpecifier: return emitExportSpecifier(node as ExportSpecifier); + case SyntaxKind.AssertClause: + return emitAssertClause(node as AssertClause); + case SyntaxKind.AssertEntry: + return emitAssertEntry(node as AssertEntry); case SyntaxKind.MissingDeclaration: return; @@ -1686,6 +1671,8 @@ namespace ts { // Identifiers case SyntaxKind.Identifier: return emitIdentifier(node as Identifier); + case SyntaxKind.PrivateIdentifier: + return emitPrivateIdentifier(node as PrivateIdentifier); // Expressions case SyntaxKind.ArrayLiteralExpression: @@ -3352,6 +3339,9 @@ namespace ts { writeSpace(); } emitExpression(node.moduleSpecifier); + if (node.assertClause) { + emitWithLeadingSpace(node.assertClause); + } writeTrailingSemicolon(); } @@ -3420,9 +3410,33 @@ namespace ts { writeSpace(); emitExpression(node.moduleSpecifier); } + if (node.assertClause) { + emitWithLeadingSpace(node.assertClause); + } writeTrailingSemicolon(); } + function emitAssertClause(node: AssertClause) { + emitTokenWithComment(SyntaxKind.AssertKeyword, node.pos, writeKeyword, node); + writeSpace(); + const elements = node.elements; + emitList(node, elements, ListFormat.ImportClauseEntries); + } + + function emitAssertEntry(node: AssertEntry) { + emit(node.name); + writePunctuation(":"); + writeSpace(); + + const value = node.value; + /** @see {emitPropertyAssignment} */ + if ((getEmitFlags(value) & EmitFlags.NoLeadingComments) === 0) { + const commentRange = getCommentRange(value); + emitTrailingCommentsOfPosition(commentRange.pos); + } + emit(value); + } + function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) { let nextPos = emitTokenWithComment(SyntaxKind.ExportKeyword, node.pos, writeKeyword, node); writeSpace(); @@ -3457,6 +3471,10 @@ namespace ts { } function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) { + if (node.isTypeOnly) { + writeKeyword("type"); + writeSpace(); + } if (node.propertyName) { emit(node.propertyName); writeSpace(); diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 85b00a5ef3e35..1e820f2092697 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -34,6 +34,7 @@ namespace ts { // Class Fields Helpers createClassPrivateFieldGetHelper(receiver: Expression, state: Identifier, kind: PrivateIdentifierKind, f: Identifier | undefined): Expression; createClassPrivateFieldSetHelper(receiver: Expression, state: Identifier, value: Expression, kind: PrivateIdentifierKind, f: Identifier | undefined): Expression; + createClassPrivateFieldInHelper(state: Identifier, receiver: Expression): Expression; } export function createEmitHelperFactory(context: TransformationContext): EmitHelperFactory { @@ -75,6 +76,7 @@ namespace ts { // Class Fields Helpers createClassPrivateFieldGetHelper, createClassPrivateFieldSetHelper, + createClassPrivateFieldInHelper }; /** @@ -136,7 +138,7 @@ namespace ts { // ES2018 Helpers function createAssignHelper(attributesSegments: Expression[]) { - if (context.getCompilerOptions().target! >= ScriptTarget.ES2015) { + if (getEmitScriptTarget(context.getCompilerOptions()) >= ScriptTarget.ES2015) { return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"), /*typeArguments*/ undefined, attributesSegments); @@ -395,6 +397,10 @@ namespace ts { return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldSet"), /*typeArguments*/ undefined, args); } + function createClassPrivateFieldInHelper(state: Identifier, receiver: Expression) { + context.requestEmitHelper(classPrivateFieldInHelper); + return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldIn"), /* typeArguments*/ undefined, [state, receiver]); + } } /* @internal */ @@ -961,6 +967,29 @@ namespace ts { };` }; + /** + * Parameters: + * @param state — One of the following: + * - A WeakMap when the member is a private instance field. + * - A WeakSet when the member is a private instance method or accessor. + * - A function value that should be the undecorated class constructor when the member is a private static field, method, or accessor. + * @param receiver — The object being checked if it has the private member. + * + * Usage: + * This helper is used to transform `#field in expression` to + * `__classPrivateFieldIn(, expression)` + */ + export const classPrivateFieldInHelper: UnscopedEmitHelper = { + name: "typescript:classPrivateFieldIn", + importName: "__classPrivateFieldIn", + scoped: false, + text: ` + var __classPrivateFieldIn = (this && this.__classPrivateFieldIn) || function(state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + };` + }; + let allUnscopedEmitHelpers: ReadonlyESMap | undefined; export function getAllUnscopedEmitHelpers() { @@ -986,6 +1015,7 @@ namespace ts { exportStarHelper, classPrivateFieldGetHelper, classPrivateFieldSetHelper, + classPrivateFieldInHelper, createBindingHelper, setModuleDefaultHelper ], helper => helper.name)); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index c697a04860b71..b87d54e5dab5a 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -289,6 +289,10 @@ namespace ts { updateImportDeclaration, createImportClause, updateImportClause, + createAssertClause, + updateAssertClause, + createAssertEntry, + updateAssertEntry, createNamespaceImport, updateNamespaceImport, createNamespaceExport, @@ -3939,7 +3943,8 @@ namespace ts { decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, - moduleSpecifier: Expression + moduleSpecifier: Expression, + assertClause: AssertClause | undefined ): ImportDeclaration { const node = createBaseDeclaration( SyntaxKind.ImportDeclaration, @@ -3948,6 +3953,7 @@ namespace ts { ); node.importClause = importClause; node.moduleSpecifier = moduleSpecifier; + node.assertClause = assertClause; node.transformFlags |= propagateChildFlags(node.importClause) | propagateChildFlags(node.moduleSpecifier); @@ -3961,13 +3967,15 @@ namespace ts { decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, - moduleSpecifier: Expression + moduleSpecifier: Expression, + assertClause: AssertClause | undefined ) { return node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier - ? update(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) + || node.assertClause !== assertClause + ? update(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, assertClause), node) : node; } @@ -3996,6 +4004,40 @@ namespace ts { : node; } + // @api + function createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause { + const node = createBaseNode(SyntaxKind.AssertClause); + node.elements = elements; + node.multiLine = multiLine; + node.transformFlags |= TransformFlags.ContainsESNext; + return node; + } + + // @api + function updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause { + return node.elements !== elements + || node.multiLine !== multiLine + ? update(createAssertClause(elements, multiLine), node) + : node; + } + + // @api + function createAssertEntry(name: AssertionKey, value: StringLiteral): AssertEntry { + const node = createBaseNode(SyntaxKind.AssertEntry); + node.name = name; + node.value = value; + node.transformFlags |= TransformFlags.ContainsESNext; + return node; + } + + // @api + function updateAssertEntry(node: AssertEntry, name: AssertionKey, value: StringLiteral): AssertEntry { + return node.name !== name + || node.value !== value + ? update(createAssertEntry(name, value), node) + : node; + } + // @api function createNamespaceImport(name: Identifier): NamespaceImport { const node = createBaseNode(SyntaxKind.NamespaceImport); @@ -4047,8 +4089,9 @@ namespace ts { } // @api - function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier) { + function createImportSpecifier(isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { const node = createBaseNode(SyntaxKind.ImportSpecifier); + node.isTypeOnly = isTypeOnly; node.propertyName = propertyName; node.name = name; node.transformFlags |= @@ -4059,10 +4102,11 @@ namespace ts { } // @api - function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) { - return node.propertyName !== propertyName + function updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { + return node.isTypeOnly !== isTypeOnly + || node.propertyName !== propertyName || node.name !== name - ? update(createImportSpecifier(propertyName, name), node) + ? update(createImportSpecifier(isTypeOnly, propertyName, name), node) : node; } @@ -4107,7 +4151,8 @@ namespace ts { modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, - moduleSpecifier?: Expression + moduleSpecifier?: Expression, + assertClause?: AssertClause ) { const node = createBaseDeclaration( SyntaxKind.ExportDeclaration, @@ -4117,6 +4162,7 @@ namespace ts { node.isTypeOnly = isTypeOnly; node.exportClause = exportClause; node.moduleSpecifier = moduleSpecifier; + node.assertClause = assertClause; node.transformFlags |= propagateChildFlags(node.exportClause) | propagateChildFlags(node.moduleSpecifier); @@ -4131,14 +4177,16 @@ namespace ts { modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, - moduleSpecifier: Expression | undefined + moduleSpecifier: Expression | undefined, + assertClause: AssertClause | undefined ) { return node.decorators !== decorators || node.modifiers !== modifiers || node.isTypeOnly !== isTypeOnly || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier - ? update(createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier), node) + || node.assertClause !== assertClause + ? update(createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause), node) : node; } @@ -4159,8 +4207,9 @@ namespace ts { } // @api - function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier) { + function createExportSpecifier(isTypeOnly: boolean, propertyName: string | Identifier | undefined, name: string | Identifier) { const node = createBaseNode(SyntaxKind.ExportSpecifier); + node.isTypeOnly = isTypeOnly; node.propertyName = asName(propertyName); node.name = asName(name); node.transformFlags |= @@ -4171,10 +4220,11 @@ namespace ts { } // @api - function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) { - return node.propertyName !== propertyName + function updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) { + return node.isTypeOnly !== isTypeOnly + || node.propertyName !== propertyName || node.name !== name - ? update(createExportSpecifier(propertyName, name), node) + ? update(createExportSpecifier(isTypeOnly, propertyName, name), node) : node; } @@ -5129,6 +5179,7 @@ namespace ts { node.transformFlags = propagateChildrenFlags(node.statements) | propagateChildFlags(node.endOfFileToken); + node.impliedNodeFormat = source.impliedNodeFormat; return node; } @@ -5441,7 +5492,7 @@ namespace ts { /*modifiers*/ undefined, /*isTypeOnly*/ false, createNamedExports([ - createExportSpecifier(/*propertyName*/ undefined, exportName) + createExportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, exportName) ]) ); } @@ -6050,9 +6101,9 @@ namespace ts { isEnumDeclaration(node) ? updateEnumDeclaration(node, node.decorators, modifiers, node.name, node.members) : isModuleDeclaration(node) ? updateModuleDeclaration(node, node.decorators, modifiers, node.name, node.body) : isImportEqualsDeclaration(node) ? updateImportEqualsDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.name, node.moduleReference) : - isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifiers, node.importClause, node.moduleSpecifier) : + isImportDeclaration(node) ? updateImportDeclaration(node, node.decorators, modifiers, node.importClause, node.moduleSpecifier, node.assertClause) : isExportAssignment(node) ? updateExportAssignment(node, node.decorators, modifiers, node.expression) : - isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.exportClause, node.moduleSpecifier) : + isExportDeclaration(node) ? updateExportDeclaration(node, node.decorators, modifiers, node.isTypeOnly, node.exportClause, node.moduleSpecifier, node.assertClause) : Debug.assertNever(node); } diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts index 7f5fda1994c60..274ade1886dfc 100644 --- a/src/compiler/factory/nodeTests.ts +++ b/src/compiler/factory/nodeTests.ts @@ -597,6 +597,14 @@ namespace ts { return node.kind === SyntaxKind.ImportClause; } + export function isAssertClause(node: Node): node is AssertClause { + return node.kind === SyntaxKind.AssertClause; + } + + export function isAssertEntry(node: Node): node is AssertEntry { + return node.kind === SyntaxKind.AssertEntry; + } + export function isNamespaceImport(node: Node): node is NamespaceImport { return node.kind === SyntaxKind.NamespaceImport; } diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 782a0110aba33..1e2cb936582fa 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -452,4 +452,4 @@ namespace ts { parenthesizeConstituentTypesOfUnionOrIntersectionType: nodes => cast(nodes, isNodeArray), parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray), }; -} \ No newline at end of file +} diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index fdd3200d572aa..7daa31c522732 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -481,7 +481,7 @@ namespace ts { if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) { let namedBindings: NamedImportBindings | undefined; const moduleKind = getEmitModuleKind(compilerOptions); - if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) { + if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ModuleKind.ESNext) { // use named imports const helpers = getEmitHelpers(sourceFile); if (helpers) { @@ -500,8 +500,8 @@ namespace ts { // NOTE: We don't need to care about global import collisions as this is a module. namedBindings = nodeFactory.createNamedImports( map(helperNames, name => isFileLevelUniqueName(sourceFile, name) - ? nodeFactory.createImportSpecifier(/*propertyName*/ undefined, nodeFactory.createIdentifier(name)) - : nodeFactory.createImportSpecifier(nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name)) + ? nodeFactory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, nodeFactory.createIdentifier(name)) + : nodeFactory.createImportSpecifier(/*isTypeOnly*/ false, nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name)) ) ); const parseNode = getOriginalNode(sourceFile, isSourceFile); @@ -522,7 +522,8 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), - nodeFactory.createStringLiteral(externalHelpersModuleNameText) + nodeFactory.createStringLiteral(externalHelpersModuleNameText), + /*assertClause*/ undefined ); addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); return externalHelpersImportDeclaration; @@ -538,9 +539,9 @@ namespace ts { } const moduleKind = getEmitModuleKind(compilerOptions); - let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault)) + let create = (hasExportStarsToExportValues || (getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault)) && moduleKind !== ModuleKind.System - && moduleKind < ModuleKind.ES2015; + && (moduleKind < ModuleKind.ES2015 || node.impliedNodeFormat === ModuleKind.CommonJS); if (!create) { const helpers = getEmitHelpers(node); if (helpers) { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index b5f83ae0b7109..bc606ffebe354 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -96,6 +96,7 @@ namespace ts { }; } + /*@internal*/ interface ModuleResolutionState { host: ModuleResolutionHost; compilerOptions: CompilerOptions; @@ -103,6 +104,8 @@ namespace ts { failedLookupLocations: Push; resultFromCache?: ResolvedModuleWithFailedLookupLocations; packageJsonInfoCache: PackageJsonInfoCache | undefined; + features: NodeResolutionFeatures; + conditions: string[]; } /** Just the fields that we use for module resolution. */ @@ -113,6 +116,10 @@ namespace ts { typesVersions?: MapLike>; main?: string; tsconfig?: string; + type?: string; + imports?: object; + exports?: object; + name?: string; } interface PackageJson extends PackageJsonPathFields { @@ -298,7 +305,7 @@ namespace ts { const containingDirectory = containingFile ? getDirectoryPath(containingFile) : undefined; const perFolderCache = containingDirectory ? cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference) : undefined; - let result = perFolderCache && perFolderCache.get(typeReferenceDirectiveName); + let result = perFolderCache && perFolderCache.get(typeReferenceDirectiveName, /*mode*/ undefined); if (result) { if (traceEnabled) { trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1, typeReferenceDirectiveName, containingFile); @@ -333,7 +340,7 @@ namespace ts { } const failedLookupLocations: string[] = []; - const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache }; + const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.AllFeatures, conditions: ["node", "require", "types"] }; let resolved = primaryLookup(); let primary = true; if (!resolved) { @@ -354,7 +361,7 @@ namespace ts { }; } result = { resolvedTypeReferenceDirective, failedLookupLocations }; - perFolderCache?.set(typeReferenceDirectiveName, result); + perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ undefined, result); if (traceEnabled) traceResult(result); return result; @@ -470,12 +477,21 @@ namespace ts { export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, PackageJsonInfoCache { } + export interface ModeAwareCache { + get(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): T | undefined; + set(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, value: T): this; + delete(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): this; + has(key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): boolean; + forEach(cb: (elem: T, key: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined) => void): void; + size(): number; + } + /** * Cached resolutions per containing directory. * This assumes that any module id will have the same resolution for sibling files located in the same folder. */ export interface PerDirectoryResolutionCache { - getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache; clear(): void; /** * Updates with the current compilerOptions the cache will operate with. @@ -493,7 +509,7 @@ namespace ts { * We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive. */ export interface NonRelativeModuleNameResolutionCache extends PackageJsonInfoCache { - getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache; + getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, redirectedReference?: ResolvedProjectReference): PerModuleNameCache; } export interface PackageJsonInfoCache { @@ -593,7 +609,7 @@ namespace ts { function updateRedirectsMap( options: CompilerOptions, - directoryToModuleNameMap: CacheWithRedirects>, + directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap?: CacheWithRedirects ) { if (!options.configFile) return; @@ -619,7 +635,7 @@ namespace ts { moduleNameToDirectoryMap?.setOwnOptions(options); } - function createPerDirectoryResolutionCache(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects>): PerDirectoryResolutionCache { + function createPerDirectoryResolutionCache(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects>): PerDirectoryResolutionCache { return { getOrCreateCacheForDirectory, clear, @@ -636,10 +652,59 @@ namespace ts { function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { const path = toPath(directoryName, currentDirectory, getCanonicalFileName); - return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => new Map()); + return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => createModeAwareCache()); } } + /* @internal */ + export function createModeAwareCache(): ModeAwareCache { + const underlying = new Map(); + const memoizedReverseKeys = new Map(); + + const cache: ModeAwareCache = { + get(specifier, mode) { + return underlying.get(getUnderlyingCacheKey(specifier, mode)); + }, + set(specifier, mode, value) { + underlying.set(getUnderlyingCacheKey(specifier, mode), value); + return cache; + }, + delete(specifier, mode) { + underlying.delete(getUnderlyingCacheKey(specifier, mode)); + return cache; + }, + has(specifier, mode) { + return underlying.has(getUnderlyingCacheKey(specifier, mode)); + }, + forEach(cb) { + return underlying.forEach((elem, key) => { + const [specifier, mode] = memoizedReverseKeys.get(key)!; + return cb(elem, specifier, mode); + }); + }, + size() { + return underlying.size; + } + }; + return cache; + + function getUnderlyingCacheKey(specifier: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined) { + const result = mode === undefined ? specifier : `${mode}|${specifier}`; + memoizedReverseKeys.set(result, [specifier, mode]); + return result; + } + } + + /* @internal */ + export function zipToModeAwareCache(file: SourceFile, keys: readonly string[], values: readonly V[]): ModeAwareCache { + Debug.assert(keys.length === values.length); + const map = createModeAwareCache(); + for (let i = 0; i < keys.length; ++i) { + map.set(keys[i], getModeForResolutionAtIndex(file, i), values[i]); + } + return map; + } + export function createModuleResolutionCache( currentDirectory: string, getCanonicalFileName: (s: string) => string, @@ -650,14 +715,14 @@ namespace ts { currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, options: undefined, - directoryToModuleNameMap: CacheWithRedirects>, + directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap: CacheWithRedirects, ): ModuleResolutionCache; export function createModuleResolutionCache( currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, options?: CompilerOptions, - directoryToModuleNameMap?: CacheWithRedirects>, + directoryToModuleNameMap?: CacheWithRedirects>, moduleNameToDirectoryMap?: CacheWithRedirects, ): ModuleResolutionCache { const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); @@ -683,9 +748,9 @@ namespace ts { updateRedirectsMap(options, directoryToModuleNameMap!, moduleNameToDirectoryMap); } - function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { + function getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName)); - return getOrCreateCache(moduleNameToDirectoryMap!, redirectedReference, nonRelativeModuleName, createPerModuleNameCache); + return getOrCreateCache(moduleNameToDirectoryMap!, redirectedReference, mode === undefined ? nonRelativeModuleName : `${mode}|${nonRelativeModuleName}`, createPerModuleNameCache); } function createPerModuleNameCache(): PerModuleNameCache { @@ -773,14 +838,14 @@ namespace ts { getCanonicalFileName: GetCanonicalFileName, options: undefined, packageJsonInfoCache: PackageJsonInfoCache | undefined, - directoryToModuleNameMap: CacheWithRedirects>, + directoryToModuleNameMap: CacheWithRedirects>, ): TypeReferenceDirectiveResolutionCache; export function createTypeReferenceDirectiveResolutionCache( currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, options?: CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache | undefined, - directoryToModuleNameMap?: CacheWithRedirects>, + directoryToModuleNameMap?: CacheWithRedirects>, ): TypeReferenceDirectiveResolutionCache { const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); packageJsonInfoCache ||= createPackageJsonInfoCache(currentDirectory, getCanonicalFileName); @@ -797,13 +862,14 @@ namespace ts { } } - export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined { + export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined { const containingDirectory = getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); - return perFolderCache && perFolderCache.get(moduleName); + if (!perFolderCache) return undefined; + return perFolderCache.get(moduleName, mode); } - export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations { + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (redirectedReference) { compilerOptions = redirectedReference.commandLine.options; @@ -816,7 +882,7 @@ namespace ts { } const containingDirectory = getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference); - let result = perFolderCache && perFolderCache.get(moduleName); + let result = perFolderCache && perFolderCache.get(moduleName, resolutionMode); if (result) { if (traceEnabled) { @@ -826,7 +892,20 @@ namespace ts { else { let moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { - moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic; + switch (getEmitModuleKind(compilerOptions)) { + case ModuleKind.CommonJS: + moduleResolution = ModuleResolutionKind.NodeJs; + break; + case ModuleKind.Node12: + moduleResolution = ModuleResolutionKind.Node12; + break; + case ModuleKind.NodeNext: + moduleResolution = ModuleResolutionKind.NodeNext; + break; + default: + moduleResolution = ModuleResolutionKind.Classic; + break; + } if (traceEnabled) { trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]); } @@ -839,6 +918,12 @@ namespace ts { perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/); switch (moduleResolution) { + case ModuleResolutionKind.Node12: + result = node12ModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); + break; + case ModuleResolutionKind.NodeNext: + result = nodeNextModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode); + break; case ModuleResolutionKind.NodeJs: result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference); break; @@ -852,10 +937,10 @@ namespace ts { perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null"); if (perFolderCache) { - perFolderCache.set(moduleName, result); + perFolderCache.set(moduleName, resolutionMode, result); if (!isExternalModuleNameRelative(moduleName)) { // put result in per-module name cache - cache!.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result); + cache!.getOrCreateCacheForModuleName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result); } } } @@ -1087,25 +1172,90 @@ namespace ts { return tryResolveJSModuleWorker(moduleName, initialDir, host).resolvedModule; } + /* @internal */ + enum NodeResolutionFeatures { + None = 0, + // resolving `#local` names in your own package.json + Imports = 1 << 1, + // resolving `your-own-name` from your own package.json + SelfName = 1 << 2, + // respecting the `.exports` member of packages' package.json files and its (conditional) mappings of export names + Exports = 1 << 3, + // allowing `*` in the LHS of an export to be followed by more content, eg `"./whatever/*.js"` + // not currently backported to node 12 - https://github.com/nodejs/Release/issues/690 + ExportsPatternTrailers = 1 << 4, + AllFeatures = Imports | SelfName | Exports | ExportsPatternTrailers, + + EsmMode = 1 << 5, + } + + function node12ModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, + host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, + resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { + return nodeNextModuleNameResolverWorker( + NodeResolutionFeatures.Imports | NodeResolutionFeatures.SelfName | NodeResolutionFeatures.Exports, + moduleName, + containingFile, + compilerOptions, + host, + cache, + redirectedReference, + resolutionMode + ); + } + + function nodeNextModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, + host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, + resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { + return nodeNextModuleNameResolverWorker( + NodeResolutionFeatures.AllFeatures, + moduleName, + containingFile, + compilerOptions, + host, + cache, + redirectedReference, + resolutionMode + ); + } + + function nodeNextModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations { + const containingDirectory = getDirectoryPath(containingFile); + + // es module file or cjs-like input file, use a variant of the legacy cjs resolver that supports the selected modern features + const esmMode = resolutionMode === ModuleKind.ESNext ? NodeResolutionFeatures.EsmMode : 0; + return nodeModuleNameResolverWorker(features | esmMode, moduleName, containingDirectory, compilerOptions, host, cache, compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions, redirectedReference); + } + const jsOnlyExtensions = [Extensions.JavaScript]; const tsExtensions = [Extensions.TypeScript, Extensions.JavaScript]; const tsPlusJsonExtensions = [...tsExtensions, Extensions.Json]; const tsconfigExtensions = [Extensions.TSConfig]; function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined); + return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined); } export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations; /* @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations; // eslint-disable-line @typescript-eslint/unified-signatures export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference); + return nodeModuleNameResolverWorker(NodeResolutionFeatures.None, moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference); } - function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ResolvedProjectReference | undefined): ResolvedModuleWithFailedLookupLocations { + function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ResolvedProjectReference | undefined): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache }; + // conditions are only used by the node12/nodenext resolver - there's no priority order in the list, + //it's essentially a set (priority is determined by object insertion order in the object we look at). + const state: ModuleResolutionState = { + compilerOptions, + host, + traceEnabled, + failedLookupLocations, + packageJsonInfoCache: cache, + features, + conditions: features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"] + }; const result = forEach(extensions, ext => tryResolve(ext)); return createResolvedModuleWithFailedLookupLocations(result?.value?.resolved, result?.value?.isExternalLibraryImport, failedLookupLocations, state.resultFromCache); @@ -1118,10 +1268,19 @@ namespace ts { } if (!isExternalModuleNameRelative(moduleName)) { - if (traceEnabled) { - trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); + let resolved: SearchResult | undefined; + if (features & NodeResolutionFeatures.Imports && startsWith(moduleName, "#")) { + resolved = loadModuleFromImports(extensions, moduleName, containingDirectory, state, cache, redirectedReference); + } + if (!resolved && features & NodeResolutionFeatures.SelfName) { + resolved = loadModuleFromSelfNameReference(extensions, moduleName, containingDirectory, state, cache, redirectedReference); + } + if (!resolved) { + if (traceEnabled) { + trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); + } + resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference); } - const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference); if (!resolved) return undefined; let resolvedValue = resolved.value; @@ -1237,29 +1396,46 @@ namespace ts { function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (extensions === Extensions.Json || extensions === Extensions.TSConfig) { const extensionLess = tryRemoveExtension(candidate, Extension.Json); - return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state); + const extension = extensionLess ? candidate.substring(extensionLess.length) : ""; + return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, extension, onlyRecordFailures, state); } - // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" - const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state); - if (resolvedByAddingExtension) { - return resolvedByAddingExtension; + // esm mode resolutions don't include automatic extension lookup (without additional flags, at least) + if (!(state.features & NodeResolutionFeatures.EsmMode)) { + // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" + const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, "", onlyRecordFailures, state); + if (resolvedByAddingExtension) { + return resolvedByAddingExtension; + } } + return loadModuleFromFileNoImplicitExtensions(extensions, candidate, onlyRecordFailures, state); + } + + function loadModuleFromFileNoImplicitExtensions(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJSFileExtension(candidate)) { + if (hasJSFileExtension(candidate) || (fileExtensionIs(candidate, Extension.Json) && state.compilerOptions.resolveJsonModule)) { const extensionless = removeFileExtension(candidate); + const extension = candidate.substring(extensionless.length); if (state.traceEnabled) { - const extension = candidate.substring(extensionless.length); trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } - return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state); + return tryAddingExtensions(extensionless, extensions, extension, onlyRecordFailures, state); } } + function loadJSOrExactTSFileName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { + if ((extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) && fileExtensionIsOneOf(candidate, [Extension.Dts, Extension.Dcts, Extension.Dmts])) { + const result = tryFile(candidate, onlyRecordFailures, state); + return result !== undefined ? { path: candidate, ext: forEach([Extension.Dts, Extension.Dcts, Extension.Dmts], e => fileExtensionIs(candidate, e) ? e : undefined)! } : undefined; + } + + return loadModuleFromFileNoImplicitExtensions(extensions, candidate, onlyRecordFailures, state); + } + /** Try to return an existing file that adds one of the `extensions` to `candidate`. */ - function tryAddingExtensions(candidate: string, extensions: Extensions, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { + function tryAddingExtensions(candidate: string, extensions: Extensions, originalExtension: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing const directory = getDirectoryPath(candidate); @@ -1270,11 +1446,51 @@ namespace ts { switch (extensions) { case Extensions.DtsOnly: - return tryExtension(Extension.Dts); + switch (originalExtension) { + case Extension.Mjs: + case Extension.Mts: + case Extension.Dmts: + return tryExtension(Extension.Dmts); + case Extension.Cjs: + case Extension.Cts: + case Extension.Dcts: + return tryExtension(Extension.Dcts); + case Extension.Json: + candidate += Extension.Json; + return tryExtension(Extension.Dts); + default: return tryExtension(Extension.Dts); + } case Extensions.TypeScript: - return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts); + switch (originalExtension) { + case Extension.Mjs: + case Extension.Mts: + case Extension.Dmts: + return tryExtension(Extension.Mts) || tryExtension(Extension.Dmts); + case Extension.Cjs: + case Extension.Cts: + case Extension.Dcts: + return tryExtension(Extension.Cts) || tryExtension(Extension.Dcts); + case Extension.Json: + candidate += Extension.Json; + return tryExtension(Extension.Dts); + default: + return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts); + } case Extensions.JavaScript: - return tryExtension(Extension.Js) || tryExtension(Extension.Jsx); + switch (originalExtension) { + case Extension.Mjs: + case Extension.Mts: + case Extension.Dmts: + return tryExtension(Extension.Mjs); + case Extension.Cjs: + case Extension.Cts: + case Extension.Dcts: + return tryExtension(Extension.Cjs); + case Extension.Json: + return tryExtension(Extension.Json); + default: + return tryExtension(Extension.Js) || tryExtension(Extension.Jsx); + } case Extensions.TSConfig: case Extensions.Json: return tryExtension(Extension.Json); @@ -1319,7 +1535,43 @@ namespace ts { versionPaths: VersionPaths | undefined; } - function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined { + /** + * A function for locating the package.json scope for a given path + */ + /*@internal*/ + export function getPackageScopeForPath(fileName: Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions): PackageJsonInfo | undefined { + const state: { + host: ModuleResolutionHost; + compilerOptions: CompilerOptions; + traceEnabled: boolean; + failedLookupLocations: Push; + resultFromCache?: ResolvedModuleWithFailedLookupLocations; + packageJsonInfoCache: PackageJsonInfoCache | undefined; + features: number; + conditions: never[]; + } = { + host, + compilerOptions: options, + traceEnabled: isTraceEnabled(options, host), + failedLookupLocations: [], + packageJsonInfoCache, + features: 0, + conditions: [], + }; + const parts = getPathComponents(fileName); + parts.pop(); + while (parts.length > 0) { + const pkg = getPackageJsonInfo(getPathFromPathComponents(parts), /*onlyRecordFailures*/ false, state); + if (pkg) { + return pkg; + } + parts.pop(); + } + return undefined; + } + + /*@internal*/ + export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined { const { host, traceEnabled } = state; const packageJsonPath = combinePaths(packageDirectory, "package.json"); if (onlyRecordFailures) { @@ -1420,7 +1672,10 @@ namespace ts { const packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile!, state)); if (packageFileResult) return packageFileResult; - return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state); + // esm mode resolutions don't do package `index` lookups + if (!(state.features & NodeResolutionFeatures.EsmMode)) { + return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state); + } } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ @@ -1453,7 +1708,237 @@ namespace ts { return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) }; } - function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + /* @internal */ + export function allKeysStartWithDot(obj: MapLike) { + return every(getOwnKeys(obj), k => startsWith(k, ".")); + } + + function noKeyStartsWithDot(obj: MapLike) { + return !some(getOwnKeys(obj), k => startsWith(k, ".")); + } + + function loadModuleFromSelfNameReference(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; + const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const scope = getPackageScopeForPath(directoryPath, state.packageJsonInfoCache, state.host, state.compilerOptions); + if (!scope || !scope.packageJsonContent.exports) { + return undefined; + } + if (typeof scope.packageJsonContent.name !== "string") { + return undefined; + } + const parts = getPathComponents(moduleName); // unrooted paths should have `""` as their 0th entry + const nameParts = getPathComponents(scope.packageJsonContent.name); + if (!every(nameParts, (p, i) => parts[i] === p)) { + return undefined; + } + const trailingParts = parts.slice(nameParts.length); + return loadModuleFromExports(scope, extensions, !length(trailingParts) ? "." : `.${directorySeparator}${trailingParts.join(directorySeparator)}`, state, cache, redirectedReference); + } + + function loadModuleFromExports(scope: PackageJsonInfo, extensions: Extensions, subpath: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + if (!scope.packageJsonContent.exports) { + return undefined; + } + + if (subpath === ".") { + let mainExport; + if (typeof scope.packageJsonContent.exports === "string" || Array.isArray(scope.packageJsonContent.exports) || (typeof scope.packageJsonContent.exports === "object" && noKeyStartsWithDot(scope.packageJsonContent.exports as MapLike))) { + mainExport = scope.packageJsonContent.exports; + } + else if (hasProperty(scope.packageJsonContent.exports as MapLike, ".")) { + mainExport = (scope.packageJsonContent.exports as MapLike)["."]; + } + if (mainExport) { + const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, subpath, scope, /*isImports*/ false); + return loadModuleFromTargetImportOrExport(mainExport, "", /*pattern*/ false); + } + } + else if (allKeysStartWithDot(scope.packageJsonContent.exports as MapLike)) { + if (typeof scope.packageJsonContent.exports !== "object") { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); + } + return toSearchResult(/*value*/ undefined); + } + const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, subpath, scope.packageJsonContent.exports, scope, /*isImports*/ false); + if (result) { + return result; + } + } + + if (state.traceEnabled) { + trace(state.host, Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); + } + return toSearchResult(/*value*/ undefined); + } + + function loadModuleFromImports(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + if (moduleName === "#" || startsWith(moduleName, "#/")) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Invalid_import_specifier_0_has_no_possible_resolutions, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; + const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const scope = getPackageScopeForPath(directoryPath, state.packageJsonInfoCache, state.host, state.compilerOptions); + if (!scope) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve, directoryPath); + } + return toSearchResult(/*value*/ undefined); + } + if (!scope.packageJsonContent.imports) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_no_imports_defined, scope.packageDirectory); + } + return toSearchResult(/*value*/ undefined); + } + + const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, moduleName, scope.packageJsonContent.imports, scope, /*isImports*/ true); + if (result) { + return result; + } + + if (state.traceEnabled) { + trace(state.host, Diagnostics.Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1, moduleName, scope.packageDirectory); + } + return toSearchResult(/*value*/ undefined); + } + + function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult | undefined { + const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, moduleName, scope, isImports); + + if (!endsWith(moduleName, directorySeparator) && moduleName.indexOf("*") === -1 && hasProperty(lookupTable, moduleName)) { + const target = (lookupTable as {[idx: string]: unknown})[moduleName]; + return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false); + } + const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike), k => k.indexOf("*") !== -1 || endsWith(k, "/")), (a, b) => a.length - b.length); + for (const potentialTarget of expandingKeys) { + if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) { + const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + const starPos = potentialTarget.indexOf("*"); + const subpath = moduleName.substring(potentialTarget.substring(0, starPos).length, moduleName.length - (potentialTarget.length - 1 - starPos)); + return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true); + } + else if (endsWith(potentialTarget, "*") && startsWith(moduleName, potentialTarget.substring(0, potentialTarget.length - 1))) { + const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + const subpath = moduleName.substring(potentialTarget.length - 1); + return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ true); + } + else if (startsWith(moduleName, potentialTarget)) { + const target = (lookupTable as {[idx: string]: unknown})[potentialTarget]; + const subpath = moduleName.substring(potentialTarget.length); + return loadModuleFromTargetImportOrExport(target, subpath, /*pattern*/ false); + } + } + + function matchesPatternWithTrailer(target: string, name: string) { + if (endsWith(target, "*")) return false; // handled by next case in loop + const starPos = target.indexOf("*"); + if (starPos === -1) return false; // handled by last case in loop + return startsWith(name, target.substring(0, starPos)) && endsWith(name, target.substring(starPos + 1)); + } + } + + /** + * Gets the self-recursive function specialized to retrieving the targeted import/export element for the given resolution configuration + */ + function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, scope: PackageJsonInfo, isImports: boolean) { + return loadModuleFromTargetImportOrExport; + function loadModuleFromTargetImportOrExport(target: unknown, subpath: string, pattern: boolean): SearchResult | undefined { + if (typeof target === "string") { + if (!pattern && subpath.length > 0 && !endsWith(target, "/")) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + if (!startsWith(target, "./")) { + if (isImports && !startsWith(target, "../") && !startsWith(target, "/") && !isRootedDiskPath(target)) { + const combinedLookup = pattern ? target.replace(/\*/g, subpath) : target + subpath; + const result = nodeModuleNameResolverWorker(state.features, combinedLookup, scope.packageDirectory + "/", state.compilerOptions, state.host, cache, [extensions], redirectedReference); + return toSearchResult(result.resolvedModule ? { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId, originalPath: result.resolvedModule.originalPath } : undefined); + } + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + const parts = pathIsRelative(target) ? getPathComponents(target).slice(1) : getPathComponents(target); + const partsAfterFirst = parts.slice(1); + if (partsAfterFirst.indexOf("..") >= 0 || partsAfterFirst.indexOf(".") >= 0 || partsAfterFirst.indexOf("node_modules") >= 0) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + const resolvedTarget = combinePaths(scope.packageDirectory, target); + // TODO: Assert that `resolvedTarget` is actually within the package directory? That's what the spec says.... but I'm not sure we need + // to be in the business of validating everyone's import and export map correctness. + const subpathParts = getPathComponents(subpath); + if (subpathParts.indexOf("..") >= 0 || subpathParts.indexOf(".") >= 0 || subpathParts.indexOf("node_modules") >= 0) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + const finalPath = getNormalizedAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath, state.host.getCurrentDirectory?.()); + + return toSearchResult(withPackageId(scope, loadJSOrExactTSFileName(extensions, finalPath, /*onlyRecordFailures*/ false, state))); + } + else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null + if (!Array.isArray(target)) { + for (const key of getOwnKeys(target as MapLike)) { + if (key === "default" || state.conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(state.conditions, key)) { + const subTarget = (target as MapLike)[key]; + const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern); + if (result) { + return result; + } + } + } + return undefined; + } + else { + if (!length(target)) { + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + for (const elem of target) { + const result = loadModuleFromTargetImportOrExport(elem, subpath, pattern); + if (result) { + return result; + } + } + } + } + else if (target === null) { // eslint-disable-line no-null/no-null + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_explicitly_maps_specifier_1_to_null, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); + } + return toSearchResult(/*value*/ undefined); + } + } + + /* @internal */ + export function isApplicableVersionedTypesKey(conditions: string[], key: string) { + if (conditions.indexOf("types") === -1) return false; // only apply versioned types conditions if the types condition is applied + if (!startsWith(key, "types@")) return false; + const range = VersionRange.tryParse(key.substring("types@".length)); + if (!range) return false; + return range.test(version); + } + + function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference); } @@ -1462,27 +1947,27 @@ namespace ts { return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined); } - function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference); + function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { + const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ModuleKind.ESNext : ModuleKind.CommonJS, redirectedReference); return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => { if (getBaseFileName(ancestorDirectory) !== "node_modules") { const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state); if (resolutionFromCache) { return resolutionFromCache; } - return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly)); + return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly, cache, redirectedReference)); } }); } - function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean): Resolved | undefined { + function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): Resolved | undefined { const nodeModulesFolder = combinePaths(directory, "node_modules"); const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host); if (!nodeModulesFolderExists && state.traceEnabled) { trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder); } - const packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state); + const packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state, cache, redirectedReference); if (packageResult) { return packageResult; } @@ -1495,33 +1980,41 @@ namespace ts { } nodeModulesAtTypesExists = false; } - return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, state); + return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, state, cache, redirectedReference); } } - function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState): Resolved | undefined { + function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): Resolved | undefined { const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName)); // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. let packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state); - if (packageInfo) { - const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state); - if (fromFile) { - return noPackageId(fromFile); - } + // But only if we're not respecting export maps (if we are, we might redirect around this location) + if (!(state.features & NodeResolutionFeatures.Exports)) { + if (packageInfo) { + const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state); + if (fromFile) { + return noPackageId(fromFile); + } - const fromDirectory = loadNodeModuleFromDirectoryWorker( - extensions, - candidate, - !nodeModulesDirectoryExists, - state, - packageInfo.packageJsonContent, - packageInfo.versionPaths - ); - return withPackageId(packageInfo, fromDirectory); + const fromDirectory = loadNodeModuleFromDirectoryWorker( + extensions, + candidate, + !nodeModulesDirectoryExists, + state, + packageInfo.packageJsonContent, + packageInfo.versionPaths + ); + return withPackageId(packageInfo, fromDirectory); + } } + const { packageName, rest } = parsePackageName(moduleName); const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { + // package exports are higher priority than file/directory lookups (and, if there's exports present, blocks them) + if (packageInfo && packageInfo.packageJsonContent.exports && state.features & NodeResolutionFeatures.Exports) { + return loadModuleFromExports(packageInfo, extensions, combinePaths(".", rest), state, cache, redirectedReference)?.value; + } const pathAndExtension = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) || loadNodeModuleFromDirectoryWorker( @@ -1535,7 +2028,6 @@ namespace ts { return withPackageId(packageInfo, pathAndExtension); }; - const { packageName, rest } = parsePackageName(moduleName); if (rest !== "") { // If "rest" is empty, we just did this search above. const packageDirectory = combinePaths(nodeModulesDirectory, packageName); @@ -1644,7 +2136,7 @@ namespace ts { export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache }; + const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.None, conditions: [] }; const containingDirectory = getDirectoryPath(containingFile); const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); @@ -1658,7 +2150,7 @@ namespace ts { } if (!isExternalModuleNameRelative(moduleName)) { - const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference); + const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, /*mode*/ undefined, redirectedReference); // Climb up parent directories looking for a module. const resolved = forEachAncestorDirectory(containingDirectory, directory => { const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state); @@ -1694,8 +2186,8 @@ namespace ts { trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache); } const failedLookupLocations: string[] = []; - const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache }; - const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false); + const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache, features: NodeResolutionFeatures.None, conditions: [] }; + const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false, /*cache*/ undefined, /*redirectedReference*/ undefined); return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, state.resultFromCache); } diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index f246f44c013d4..7c48d891a744c 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -11,7 +11,7 @@ namespace ts.moduleSpecifiers { readonly ending: Ending; } - function getPreferences({ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences { + function getPreferences(host: ModuleSpecifierResolutionHost, { importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences { return { relativePreference: importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : @@ -25,21 +25,40 @@ namespace ts.moduleSpecifiers { case "minimal": return Ending.Minimal; case "index": return Ending.Index; case "js": return Ending.JsExtension; - default: return usesJsExtensionOnImports(importingSourceFile) ? Ending.JsExtension + default: return usesJsExtensionOnImports(importingSourceFile) || isFormatRequiringExtensions(compilerOptions, importingSourceFile.path, host) ? Ending.JsExtension : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; } } } - function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string): Preferences { + function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Preferences { return { relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, - ending: hasJSFileExtension(oldImportSpecifier) ? + ending: hasJSFileExtension(oldImportSpecifier) || isFormatRequiringExtensions(compilerOptions, importingSourceFileName, host) ? Ending.JsExtension : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, }; } + function isFormatRequiringExtensions(compilerOptions: CompilerOptions, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost) { + if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node12 + && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) { + return false; + } + return getImpliedNodeFormatForFile(importingSourceFileName, /*packageJsonInfoCache*/ undefined, getModuleResolutionHost(host), compilerOptions) !== ModuleKind.CommonJS; + } + + function getModuleResolutionHost(host: ModuleSpecifierResolutionHost): ModuleResolutionHost { + return { + fileExists: host.fileExists, + readFile: Debug.checkDefined(host.readFile), + directoryExists: host.directoryExists, + getCurrentDirectory: host.getCurrentDirectory, + realpath: host.realpath, + useCaseSensitiveFileNames: host.useCaseSensitiveFileNames?.(), + }; + } + export function updateModuleSpecifier( compilerOptions: CompilerOptions, importingSourceFileName: Path, @@ -47,7 +66,7 @@ namespace ts.moduleSpecifiers { host: ModuleSpecifierResolutionHost, oldImportSpecifier: string, ): string | undefined { - const res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier), {}); + const res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier, importingSourceFileName, host), {}); if (res === oldImportSpecifier) return undefined; return res; } @@ -60,7 +79,7 @@ namespace ts.moduleSpecifiers { toFileName: string, host: ModuleSpecifierResolutionHost, ): string { - return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferences({}, compilerOptions, importingSourceFile), {}); + return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferences(host, {}, compilerOptions, importingSourceFile), {}); } export function getNodeModulesPackageName( @@ -175,7 +194,7 @@ namespace ts.moduleSpecifiers { userPreferences: UserPreferences, ): readonly string[] { const info = getInfo(importingSourceFile.path, host); - const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); + const preferences = getPreferences(host, userPreferences, compilerOptions, importingSourceFile); const existingSpecifier = forEach(modulePaths, modulePath => forEach( host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), reason => { @@ -536,6 +555,77 @@ namespace ts.moduleSpecifiers { } } + const enum MatchingMode { + Exact, + Directory, + Pattern + } + + function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[], mode = MatchingMode.Exact): { moduleFileToTry: string } | undefined { + if (typeof exports === "string") { + const pathOrPattern = getNormalizedAbsolutePath(combinePaths(packageDirectory, exports), /*currentDirectory*/ undefined); + const extensionSwappedTarget = hasTSFileExtension(targetFilePath) ? removeFileExtension(targetFilePath) + tryGetJSExtensionForFile(targetFilePath, options) : undefined; + switch (mode) { + case MatchingMode.Exact: + if (comparePaths(targetFilePath, pathOrPattern) === Comparison.EqualTo || (extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern) === Comparison.EqualTo)) { + return { moduleFileToTry: packageName }; + } + break; + case MatchingMode.Directory: + if (containsPath(pathOrPattern, targetFilePath)) { + const fragment = getRelativePathFromDirectory(pathOrPattern, targetFilePath, /*ignoreCase*/ false); + return { moduleFileToTry: getNormalizedAbsolutePath(combinePaths(combinePaths(packageName, exports), fragment), /*currentDirectory*/ undefined) }; + } + break; + case MatchingMode.Pattern: + const starPos = pathOrPattern.indexOf("*"); + const leadingSlice = pathOrPattern.slice(0, starPos); + const trailingSlice = pathOrPattern.slice(starPos + 1); + if (startsWith(targetFilePath, leadingSlice) && endsWith(targetFilePath, trailingSlice)) { + const starReplacement = targetFilePath.slice(leadingSlice.length, targetFilePath.length - trailingSlice.length); + return { moduleFileToTry: packageName.replace("*", starReplacement) }; + } + if (extensionSwappedTarget && startsWith(extensionSwappedTarget, leadingSlice) && endsWith(extensionSwappedTarget, trailingSlice)) { + const starReplacement = extensionSwappedTarget.slice(leadingSlice.length, extensionSwappedTarget.length - trailingSlice.length); + return { moduleFileToTry: packageName.replace("*", starReplacement) }; + } + break; + } + } + else if (Array.isArray(exports)) { + return forEach(exports, e => tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, e, conditions)); + } + else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null + if (allKeysStartWithDot(exports as MapLike)) { + // sub-mappings + // 3 cases: + // * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode)) + // * pattern mappings (contains a *) + // * exact mappings (no *, does not end with /) + return forEach(getOwnKeys(exports as MapLike), k => { + const subPackageName = getNormalizedAbsolutePath(combinePaths(packageName, k), /*currentDirectory*/ undefined); + const mode = endsWith(k, "/") ? MatchingMode.Directory + : stringContains(k, "*") ? MatchingMode.Pattern + : MatchingMode.Exact; + return tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, subPackageName, (exports as MapLike)[k], conditions, mode); + }); + } + else { + // conditional mapping + for (const key of getOwnKeys(exports as MapLike)) { + if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) { + const subTarget = (exports as MapLike)[key]; + const result = tryGetModuleNameFromExports(options, targetFilePath, packageDirectory, packageName, subTarget, conditions); + if (result) { + return result; + } + } + } + } + } + return undefined; + } + function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: Ending, compilerOptions: CompilerOptions): string | undefined { const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPath === undefined) { @@ -567,7 +657,15 @@ namespace ts.moduleSpecifiers { let moduleFileNameForExtensionless: string | undefined; while (true) { // If the module could be imported by a directory name, use that directory's name - const { moduleFileToTry, packageRootPath } = tryDirectoryWithPackageJson(packageRootIndex); + const { moduleFileToTry, packageRootPath, blockedByExports, verbatimFromExports } = tryDirectoryWithPackageJson(packageRootIndex); + if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Classic) { + if (blockedByExports) { + return undefined; // File is under this package.json, but is not publicly exported - there's no way to name it via `node_modules` resolution + } + if (verbatimFromExports) { + return moduleFileToTry; + } + } if (packageRootPath) { moduleSpecifier = packageRootPath; isPackageRootPath = true; @@ -600,14 +698,23 @@ namespace ts.moduleSpecifiers { const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1); const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName); // For classic resolution, only allow importing from node_modules/@types, not other node_modules - return getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName; + return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Classic && packageName === nodeModulesDirectoryName ? undefined : packageName; - function tryDirectoryWithPackageJson(packageRootIndex: number) { + function tryDirectoryWithPackageJson(packageRootIndex: number): { moduleFileToTry: string, packageRootPath?: string, blockedByExports?: true, verbatimFromExports?: true } { const packageRootPath = path.substring(0, packageRootIndex); const packageJsonPath = combinePaths(packageRootPath, "package.json"); let moduleFileToTry = path; if (host.fileExists(packageJsonPath)) { const packageJsonContent = JSON.parse(host.readFile!(packageJsonPath)!); + // TODO: Inject `require` or `import` condition based on the intended import mode + const fromExports = packageJsonContent.exports && typeof packageJsonContent.name === "string" ? tryGetModuleNameFromExports(options, path, packageRootPath, packageJsonContent.name, packageJsonContent.exports, ["node", "types"]) : undefined; + if (fromExports) { + const withJsExtension = !hasTSFileExtension(fromExports.moduleFileToTry) ? fromExports : { moduleFileToTry: removeFileExtension(fromExports.moduleFileToTry) + tryGetJSExtensionForFile(fromExports.moduleFileToTry, options) }; + return { ...withJsExtension, verbatimFromExports: true }; + } + if (packageJsonContent.exports) { + return { moduleFileToTry: path, blockedByExports: true }; + } const versionPaths = packageJsonContent.typesVersions ? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions) : undefined; @@ -622,7 +729,6 @@ namespace ts.moduleSpecifiers { moduleFileToTry = combinePaths(packageRootPath, fromPaths); } } - // If the file is the main module, it can be imported by the package name const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; if (isString(mainFileRelative)) { @@ -652,7 +758,7 @@ namespace ts.moduleSpecifiers { function tryGetAnyFileFromPath(host: ModuleSpecifierResolutionHost, path: string) { if (!host.fileExists) return; // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory - const extensions = getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }]); + const extensions = flatten(getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }])); for (const e of extensions) { const fullPath = path + e; if (host.fileExists(fullPath)) { @@ -733,8 +839,9 @@ namespace ts.moduleSpecifiers { } function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions): string { - if (fileExtensionIs(fileName, Extension.Json)) return fileName; + if (fileExtensionIsOneOf(fileName, [Extension.Json, Extension.Mjs, Extension.Cjs])) return fileName; const noExtension = removeFileExtension(fileName); + if (fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Dcts, Extension.Cts])) return noExtension + getJSExtensionForFile(fileName, options); switch (ending) { case Ending.Minimal: return removeSuffix(noExtension, "/index"); @@ -763,6 +870,14 @@ namespace ts.moduleSpecifiers { case Extension.Jsx: case Extension.Json: return ext; + case Extension.Dmts: + case Extension.Mts: + case Extension.Mjs: + return Extension.Mjs; + case Extension.Dcts: + case Extension.Cts: + case Extension.Cjs: + return Extension.Cjs; default: return undefined; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0aa0a8fb0957f..4182d621cfafe 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -398,13 +398,18 @@ namespace ts { return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, (node as ImportDeclaration).importClause) || - visitNode(cbNode, (node as ImportDeclaration).moduleSpecifier); + visitNode(cbNode, (node as ImportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ImportDeclaration).assertClause); case SyntaxKind.ImportClause: return visitNode(cbNode, (node as ImportClause).name) || visitNode(cbNode, (node as ImportClause).namedBindings); + case SyntaxKind.AssertClause: + return visitNodes(cbNode, cbNodes, (node as AssertClause).elements); + case SyntaxKind.AssertEntry: + return visitNode(cbNode, (node as AssertEntry).name) || + visitNode(cbNode, (node as AssertEntry).value); case SyntaxKind.NamespaceExportDeclaration: return visitNode(cbNode, (node as NamespaceExportDeclaration).name); - case SyntaxKind.NamespaceImport: return visitNode(cbNode, (node as NamespaceImport).name); case SyntaxKind.NamespaceExport: @@ -416,7 +421,8 @@ namespace ts { return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, (node as ExportDeclaration).exportClause) || - visitNode(cbNode, (node as ExportDeclaration).moduleSpecifier); + visitNode(cbNode, (node as ExportDeclaration).moduleSpecifier) || + visitNode(cbNode, (node as ExportDeclaration).assertClause); case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: return visitNode(cbNode, (node as ImportOrExportSpecifier).propertyName) || @@ -1633,7 +1639,7 @@ namespace ts { parseErrorAtCurrentToken(blankDiagnostic); } else { - parseErrorAtCurrentToken(nameDiagnostic, tokenToString(token())); + parseErrorAtCurrentToken(nameDiagnostic, scanner.getTokenValue()); } } @@ -1886,6 +1892,11 @@ namespace ts { token() === SyntaxKind.NumericLiteral; } + function isAssertionKey(): boolean { + return tokenIsIdentifierOrKeyword(token()) || + token() === SyntaxKind.StringLiteral; + } + function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) { const node = parseLiteralNode() as StringLiteral | NumericLiteral; @@ -1963,7 +1974,6 @@ namespace ts { case SyntaxKind.DefaultKeyword: return nextTokenCanFollowDefaultKeyword(); case SyntaxKind.StaticKeyword: - return nextTokenIsOnSameLineAndCanFollowModifier(); case SyntaxKind.GetKeyword: case SyntaxKind.SetKeyword: nextToken(); @@ -2051,6 +2061,8 @@ namespace ts { return isLiteralPropertyName(); case ParsingContext.ObjectBindingElements: return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); + case ParsingContext.AssertEntries: + return isAssertionKey(); case ParsingContext.HeritageClauseElement: // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` // That way we won't consume the body of a class in its heritage clause. @@ -2171,6 +2183,7 @@ namespace ts { case ParsingContext.ObjectLiteralMembers: case ParsingContext.ObjectBindingElements: case ParsingContext.ImportOrExportSpecifiers: + case ParsingContext.AssertEntries: return token() === SyntaxKind.CloseBraceToken; case ParsingContext.SwitchClauseStatements: return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; @@ -5042,12 +5055,12 @@ namespace ts { && !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName) && tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName)) { // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, - // restructure (

(...
)) --> (
(...)
) + // restructure (
(......
)) --> (
(......)
) // (no need to error; the parent will error) - const end = lastChild.openingElement.end; // newly-created children and closing are both zero-width end/end + const end = lastChild.children.end; const newLast = finishNode(factory.createJsxElement( lastChild.openingElement, - createNodeArray([], end, end), + lastChild.children, finishNode(factory.createJsxClosingElement(finishNode(factory.createIdentifier(""), end, end)), end, end)), lastChild.openingElement.pos, end); @@ -5603,6 +5616,8 @@ namespace ts { break; case SyntaxKind.TemplateHead: return parseTemplateExpression(/* isTaggedTemplate */ false); + case SyntaxKind.PrivateIdentifier: + return parsePrivateIdentifier(); } return parseIdentifier(Diagnostics.Expression_expected); @@ -6854,7 +6869,7 @@ namespace ts { return list && createNodeArray(list, pos); } - function tryParseModifier(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): Modifier | undefined { + function tryParseModifier(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean, hasSeenStaticModifier?: boolean): Modifier | undefined { const pos = getNodePos(); const kind = token(); @@ -6868,6 +6883,9 @@ namespace ts { else if (stopOnStartOfClassStaticBlock && token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { return undefined; } + else if (hasSeenStaticModifier && token() === SyntaxKind.StaticKeyword) { + return undefined; + } else { if (!parseAnyContextualModifier()) { return undefined; @@ -6886,8 +6904,9 @@ namespace ts { */ function parseModifiers(permitInvalidConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined { const pos = getNodePos(); - let list, modifier; - while (modifier = tryParseModifier(permitInvalidConstAsModifier, stopOnStartOfClassStaticBlock)) { + let list, modifier, hasSeenStatic = false; + while (modifier = tryParseModifier(permitInvalidConstAsModifier, stopOnStartOfClassStaticBlock, hasSeenStatic)) { + if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStatic = true; list = append(list, modifier); } return list && createNodeArray(list, pos); @@ -7234,13 +7253,45 @@ namespace ts { importClause = parseImportClause(identifier, afterImportPos, isTypeOnly); parseExpected(SyntaxKind.FromKeyword); } - const moduleSpecifier = parseModuleSpecifier(); + + let assertClause: AssertClause | undefined; + if (token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { + assertClause = parseAssertClause(); + } + parseSemicolon(); - const node = factory.createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier); + const node = factory.createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier, assertClause); return withJSDoc(finishNode(node, pos), hasJSDoc); } + function parseAssertEntry() { + const pos = getNodePos(); + const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral; + parseExpected(SyntaxKind.ColonToken); + const value = parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral; + return finishNode(factory.createAssertEntry(name, value), pos); + } + + function parseAssertClause() { + const pos = getNodePos(); + parseExpected(SyntaxKind.AssertKeyword); + const openBracePosition = scanner.getTokenPos(); + parseExpected(SyntaxKind.OpenBraceToken); + const multiLine = scanner.hasPrecedingLineBreak(); + const elements = parseDelimitedList(ParsingContext.AssertEntries, parseAssertEntry, /*considerSemicolonAsDelimiter*/ true); + if (!parseExpected(SyntaxKind.CloseBraceToken)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here) + ); + } + } + return finishNode(factory.createAssertClause(elements, multiLine), pos); + } + function tokenAfterImportDefinitelyProducesImportDeclaration() { return token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken; } @@ -7356,27 +7407,76 @@ namespace ts { let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); let checkIdentifierStart = scanner.getTokenPos(); let checkIdentifierEnd = scanner.getTextPos(); - const identifierName = parseIdentifierName(); + let isTypeOnly = false; let propertyName: Identifier | undefined; - let name: Identifier; - if (token() === SyntaxKind.AsKeyword) { - propertyName = identifierName; - parseExpected(SyntaxKind.AsKeyword); - checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); - checkIdentifierStart = scanner.getTokenPos(); - checkIdentifierEnd = scanner.getTextPos(); - name = parseIdentifierName(); + let canParseAsKeyword = true; + let name = parseIdentifierName(); + if (name.escapedText === "type") { + // If the first token of an import specifier is 'type', there are a lot of possibilities, + // especially if we see 'as' afterwards: + // + // import { type } from "mod"; - isTypeOnly: false, name: type + // import { type as } from "mod"; - isTypeOnly: true, name: as + // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type + // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as + if (token() === SyntaxKind.AsKeyword) { + // { type as ...? } + const firstAs = parseIdentifierName(); + if (token() === SyntaxKind.AsKeyword) { + // { type as as ...? } + const secondAs = parseIdentifierName(); + if (tokenIsIdentifierOrKeyword(token())) { + // { type as as something } + isTypeOnly = true; + propertyName = firstAs; + name = parseNameWithKeywordCheck(); + canParseAsKeyword = false; + } + else { + // { type as as } + propertyName = name; + name = secondAs; + canParseAsKeyword = false; + } + } + else if (tokenIsIdentifierOrKeyword(token())) { + // { type as something } + propertyName = name; + canParseAsKeyword = false; + name = parseNameWithKeywordCheck(); + } + else { + // { type as } + isTypeOnly = true; + name = firstAs; + } + } + else if (tokenIsIdentifierOrKeyword(token())) { + // { type something ...? } + isTypeOnly = true; + name = parseNameWithKeywordCheck(); + } } - else { - name = identifierName; + + if (canParseAsKeyword && token() === SyntaxKind.AsKeyword) { + propertyName = name; + parseExpected(SyntaxKind.AsKeyword); + name = parseNameWithKeywordCheck(); } if (kind === SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) { parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected); } const node = kind === SyntaxKind.ImportSpecifier - ? factory.createImportSpecifier(propertyName, name) - : factory.createExportSpecifier(propertyName, name); + ? factory.createImportSpecifier(isTypeOnly, propertyName, name) + : factory.createExportSpecifier(isTypeOnly, propertyName, name); return finishNode(node, pos); + + function parseNameWithKeywordCheck() { + checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + checkIdentifierStart = scanner.getTokenPos(); + checkIdentifierEnd = scanner.getTextPos(); + return parseIdentifierName(); + } } function parseNamespaceExport(pos: number): NamespaceExport { @@ -7388,6 +7488,7 @@ namespace ts { setAwaitContext(/*value*/ true); let exportClause: NamedExportBindings | undefined; let moduleSpecifier: Expression | undefined; + let assertClause: AssertClause | undefined; const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); const namespaceExportPos = getNodePos(); if (parseOptional(SyntaxKind.AsteriskToken)) { @@ -7407,9 +7508,12 @@ namespace ts { moduleSpecifier = parseModuleSpecifier(); } } + if (moduleSpecifier && token() === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak()) { + assertClause = parseAssertClause(); + } parseSemicolon(); setAwaitContext(savedAwaitContext); - const node = factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier); + const node = factory.createExportDeclaration(decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause); return withJSDoc(finishNode(node, pos), hasJSDoc); } @@ -7489,7 +7593,8 @@ namespace ts { TypeArguments, // Type arguments in type argument list TupleElementTypes, // Element types in tuple element type list HeritageClauses, // Heritage clauses for a class or interface declaration. - ImportOrExportSpecifiers, // Named import clause's import specifier list + ImportOrExportSpecifiers, // Named import clause's import specifier list, + AssertEntries, // Import entries list. Count // Number of parsing contexts } @@ -8441,11 +8546,24 @@ namespace ts { function parseTemplateTagTypeParameter() { const typeParameterPos = getNodePos(); + const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); + if (isBracketed) { + skipWhitespace(); + } const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); + + let defaultType: TypeNode | undefined; + if (isBracketed) { + skipWhitespace(); + parseExpected(SyntaxKind.EqualsToken); + defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); + parseExpected(SyntaxKind.CloseBracketToken); + } + if (nodeIsMissing(name)) { return undefined; } - return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined), typeParameterPos); + return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, defaultType), typeParameterPos); } function parseTemplateTagTypeParameters() { @@ -8611,6 +8729,7 @@ namespace ts { newText, aggressiveChecks ); + result.impliedNodeFormat = sourceFile.impliedNodeFormat; return result; } @@ -9151,7 +9270,7 @@ namespace ts { /** @internal */ export function isDeclarationFileName(fileName: string): boolean { - return fileExtensionIs(fileName, Extension.Dts); + return fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Dmts, Extension.Dcts]); } /*@internal*/ diff --git a/src/compiler/program.ts b/src/compiler/program.ts index f7c0f00932f6f..045a31d457648 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -529,6 +529,58 @@ namespace ts { return resolutions; } + /* @internal */ + interface SourceFileImportsList { + imports: SourceFile["imports"]; + moduleAugmentations: SourceFile["moduleAugmentations"]; + impliedNodeFormat?: SourceFile["impliedNodeFormat"]; + }; + + /* @internal */ + export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number) { + if (file.impliedNodeFormat === undefined) return undefined; + // we ensure all elements of file.imports and file.moduleAugmentations have the relevant parent pointers set during program setup, + // so it's safe to use them even pre-bind + return getModeForUsageLocation(file, getModuleNameStringLiteralAt(file, index)); + } + + /* @internal */ + export function getModeForUsageLocation(file: {impliedNodeFormat?: SourceFile["impliedNodeFormat"]}, usage: StringLiteralLike) { + if (file.impliedNodeFormat === undefined) return undefined; + if (file.impliedNodeFormat !== ModuleKind.ESNext) { + // in cjs files, import call expressions are esm format, otherwise everything is cjs + return isImportCall(walkUpParenthesizedExpressions(usage.parent)) ? ModuleKind.ESNext : ModuleKind.CommonJS; + } + // in esm files, import=require statements are cjs format, otherwise everything is esm + // imports are only parent'd up to their containing declaration/expression, so access farther parents with care + const exprParentParent = walkUpParenthesizedExpressions(usage.parent)?.parent; + return exprParentParent && isImportEqualsDeclaration(exprParentParent) ? ModuleKind.CommonJS : ModuleKind.ESNext; + } + + /* @internal */ + export function loadWithModeAwareCache(names: string[], containingFile: SourceFile, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] { + if (names.length === 0) { + return []; + } + const resolutions: T[] = []; + const cache = new Map(); + let i = 0; + for (const name of names) { + let result: T; + const mode = getModeForResolutionAtIndex(containingFile, i); + i++; + const cacheKey = mode !== undefined ? `${mode}|${name}` : name; + if (cache.has(cacheKey)) { + result = cache.get(cacheKey)!; + } + else { + cache.set(cacheKey, result = loader(name, mode, containingFileName, redirectedReference)); + } + resolutions.push(result); + } + return resolutions; + } + /* @internal */ export function forEachResolvedProjectReference( resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, @@ -623,7 +675,7 @@ namespace ts { switch (kind) { case FileIncludeKind.Import: const importLiteral = getModuleNameStringLiteralAt(file, index); - packageId = file.resolvedModules?.get(importLiteral.text)?.packageId; + packageId = file.resolvedModules?.get(importLiteral.text, getModeForResolutionAtIndex(file, index))?.packageId; if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text }; pos = skipTrivia(file.text, importLiteral.pos); end = importLiteral.end; @@ -633,7 +685,7 @@ namespace ts { break; case FileIncludeKind.TypeReferenceDirective: ({ pos, end } = file.typeReferenceDirectives[index]); - packageId = file.resolvedTypeReferenceDirectiveNames?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName))?.packageId; + packageId = file.resolvedTypeReferenceDirectiveNames?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), getModeForResolutionAtIndex(file, index))?.packageId; break; case FileIncludeKind.LibReferenceDirective: ({ pos, end } = file.libReferenceDirectives[index]); @@ -738,6 +790,34 @@ namespace ts { configFileParseResult.errors; } + /** + * A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the + * `options` parameter. + * + * @param fileName The normalized absolute path to check the format of (it need not exist on disk) + * @param [packageJsonInfoCache] A cache for package file lookups - it's best to have a cache when this function is called often + * @param host The ModuleResolutionHost which can perform the filesystem lookups for package json data + * @param options The compiler options to perform the analysis under - relevant options are `moduleResolution` and `traceResolution` + * @returns `undefined` if the path has no relevant implied format, `ModuleKind.ESNext` for esm format, and `ModuleKind.CommonJS` for cjs format + */ + export function getImpliedNodeFormatForFile(fileName: Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions): ModuleKind.ESNext | ModuleKind.CommonJS | undefined { + switch (getEmitModuleResolutionKind(options)) { + case ModuleResolutionKind.Node12: + case ModuleResolutionKind.NodeNext: + return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext : + fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS : + fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() : + undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline + default: + return undefined; + } + function lookupFromPackageJson(): ModuleKind.ESNext | ModuleKind.CommonJS { + const scope = getPackageScopeForPath(fileName, packageJsonInfoCache, host, options); + return scope?.packageJsonContent.type === "module" ? ModuleKind.ESNext : ModuleKind.CommonJS; + + } + } + /** * Determine if source file needs to be re-created even if its text hasn't changed */ @@ -834,7 +914,7 @@ namespace ts { const programDiagnostics = createDiagnosticCollection(); const currentDirectory = host.getCurrentDirectory(); const supportedExtensions = getSupportedExtensions(options); - const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); + const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions); // Map storing if there is emit blocking diagnostics for given input const hasEmitBlockingDiagnostics = new Map(); @@ -842,10 +922,10 @@ namespace ts { let moduleResolutionCache: ModuleResolutionCache | undefined; let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined; - let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[]; + let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: SourceFile, containingFileName: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[]; const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse; if (host.resolveModuleNames) { - actualResolveModuleNamesWorker = (moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.checkEachDefined(moduleNames), containingFile, reusedNames, redirectedReference, options).map(resolved => { + actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.checkEachDefined(moduleNames), containingFileName, reusedNames, redirectedReference, options, containingFile).map(resolved => { // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName. if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) { return resolved as ResolvedModuleFull; @@ -854,11 +934,12 @@ namespace ts { withExtension.extension = extensionFromPath(resolved.resolvedFileName); return withExtension; }); + moduleResolutionCache = host.getModuleResolutionCache?.(); } else { moduleResolutionCache = createModuleResolutionCache(currentDirectory, getCanonicalFileName, options); - const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule!; // TODO: GH#18217 - actualResolveModuleNamesWorker = (moduleNames, containingFile, _reusedNames, redirectedReference) => loadWithLocalCache(Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader); + const loader = (moduleName: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFileName: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFileName, options, host, moduleResolutionCache, redirectedReference, resolverMode).resolvedModule!; // TODO: GH#18217 + actualResolveModuleNamesWorker = (moduleNames, containingFile, containingFileName, _reusedNames, redirectedReference) => loadWithModeAwareCache(Debug.checkEachDefined(moduleNames), containingFile, containingFileName, redirectedReference, loader); } let actualResolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference) => (ResolvedTypeReferenceDirective | undefined)[]; @@ -917,6 +998,7 @@ namespace ts { getSourceOfProjectReferenceRedirect, forEachResolvedProjectReference }); + const readFile = host.readFile.bind(host) as typeof host.readFile; tracing?.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram }); const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); @@ -995,7 +1077,7 @@ namespace ts { } else { forEach(options.lib, (libFileName, index) => { - processRootFile(combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile, index }); + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false, { kind: FileIncludeKind.LibFile, index }); }); } } @@ -1101,6 +1183,7 @@ namespace ts { isSourceOfProjectReferenceRedirect, emitBuildInfo, fileExists, + readFile, directoryExists, getSymlinkCache, realpath: host.realpath?.bind(host), @@ -1137,7 +1220,7 @@ namespace ts { const redirectedReference = getRedirectReferenceForResolution(containingFile); tracing?.push(tracing.Phase.Program, "resolveModuleNamesWorker", { containingFileName }); performance.mark("beforeResolveModule"); - const result = actualResolveModuleNamesWorker(moduleNames, containingFileName, reusedNames, redirectedReference); + const result = actualResolveModuleNamesWorker(moduleNames, containingFile, containingFileName, reusedNames, redirectedReference); performance.mark("afterResolveModule"); performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule"); tracing?.pop(); @@ -1159,7 +1242,7 @@ namespace ts { function getRedirectReferenceForResolution(file: SourceFile) { const redirect = getResolvedProjectReferenceToRedirect(file.originalFileName); - if (redirect || !fileExtensionIs(file.originalFileName, Extension.Dts)) return redirect; + if (redirect || !fileExtensionIsOneOf(file.originalFileName, [Extension.Dts, Extension.Dcts, Extension.Dmts])) return redirect; // The originalFileName could not be actual source file name if file found was d.ts from referecned project // So in this case try to look up if this is output from referenced project, if it is use the redirected project in that case @@ -1202,8 +1285,8 @@ namespace ts { return libs.length + 2; } - function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined { - return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache); + function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, mode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined { + return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache, mode); } function toPath(fileName: string): Path { @@ -1256,8 +1339,10 @@ namespace ts { // Since we assume the filesystem does not change during program creation, // it is safe to reuse resolutions from the earlier call. const result: ResolvedModuleFull[] = []; + let i = 0; for (const moduleName of moduleNames) { - const resolvedModule = file.resolvedModules.get(moduleName)!; + const resolvedModule = file.resolvedModules.get(moduleName, getModeForResolutionAtIndex(file, i))!; + i++; result.push(resolvedModule); } return result; @@ -1287,7 +1372,7 @@ namespace ts { const moduleName = moduleNames[i]; // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) { - const oldResolvedModule = getResolvedModule(oldSourceFile, moduleName); + const oldResolvedModule = getResolvedModule(oldSourceFile, moduleName, getModeForResolutionAtIndex(oldSourceFile, i)); if (oldResolvedModule) { if (isTraceEnabled(options, host)) { trace(host, @@ -1317,7 +1402,7 @@ namespace ts { } } else { - resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName); + resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, i); } if (resolvesToAmbientModuleInNonModifiedFile) { @@ -1360,8 +1445,9 @@ namespace ts { // If we change our policy of rechecking failed lookups on each program create, // we should adjust the value returned here. - function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string): boolean { - const resolutionToFile = getResolvedModule(oldSourceFile, moduleName); + function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, index: number): boolean { + if (index >= length(oldSourceFile?.imports) + length(oldSourceFile?.moduleAugmentations)) return false; // mode index out of bounds, don't reuse resolution + const resolutionToFile = getResolvedModule(oldSourceFile, moduleName, oldSourceFile && getModeForResolutionAtIndex(oldSourceFile, index)); const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName); if (resolutionToFile && resolvedFile) { // In the old program, we resolved to an ambient module that was in the same @@ -1455,8 +1541,8 @@ namespace ts { for (const oldSourceFile of oldSourceFiles) { let newSourceFile = host.getSourceFileByPath - ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile) - : host.getSourceFile(oldSourceFile.fileName, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217 + ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, getEmitScriptTarget(options), /*onError*/ undefined, shouldCreateNewSourceFile) + : host.getSourceFile(oldSourceFile.fileName, getEmitScriptTarget(options), /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217 if (!newSourceFile) { return StructureIsReused.Not; @@ -1576,10 +1662,10 @@ namespace ts { const moduleNames = getModuleNames(newSourceFile); const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile); // ensure that module resolution results are still correct - const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo); + const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, oldSourceFile, moduleResolutionIsEqualTo); if (resolutionsChanged) { structureIsReused = StructureIsReused.SafeModules; - newSourceFile.resolvedModules = zipToMap(moduleNames, resolutions); + newSourceFile.resolvedModules = zipToModeAwareCache(newSourceFile, moduleNames, resolutions); } else { newSourceFile.resolvedModules = oldSourceFile.resolvedModules; @@ -1588,10 +1674,10 @@ namespace ts { const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => toFileNameLowerCase(ref.fileName)); const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFile); // ensure that types resolutions are still correct - const typeReferenceEesolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo); + const typeReferenceEesolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, typeReferenceResolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, oldSourceFile, typeDirectiveIsEqualTo); if (typeReferenceEesolutionsChanged) { structureIsReused = StructureIsReused.SafeModules; - newSourceFile.resolvedTypeReferenceDirectiveNames = zipToMap(typesReferenceDirectives, typeReferenceResolutions); + newSourceFile.resolvedTypeReferenceDirectiveNames = zipToModeAwareCache(newSourceFile, typesReferenceDirectives, typeReferenceResolutions); } else { newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames; @@ -1737,7 +1823,7 @@ namespace ts { return equalityComparer(file.fileName, getDefaultLibraryFileName()); } else { - return some(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName))); + return some(options.lib, libFileName => equalityComparer(file.fileName, pathForLibFile(libFileName))); } } @@ -2269,7 +2355,7 @@ namespace ts { function createSyntheticImport(text: string, file: SourceFile) { const externalHelpersModuleReference = factory.createStringLiteral(text); - const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); + const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference, /*assertClause*/ undefined); addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); setParent(externalHelpersModuleReference, importDecl); setParent(importDecl, file); @@ -2328,6 +2414,7 @@ namespace ts { // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules // only through top - level external module names. Relative external module names are not permitted. if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !isExternalModuleNameRelative(moduleNameExpr.text))) { + setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, moduleNameExpr); if (!usesUriStyleNodeCoreModules && currentNodeModulesDepth === 0 && !file.isDeclarationFile) { usesUriStyleNodeCoreModules = startsWith(moduleNameExpr.text, "node:"); @@ -2336,6 +2423,7 @@ namespace ts { } else if (isModuleDeclaration(node)) { if (isAmbientModule(node) && (inAmbientModule || hasSyntacticModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) { + (node.name as Mutable).parent = node; const nameText = getTextOfIdentifierOrLiteral(node.name); // Ambient module declarations can be interpreted as augmentations for some existing external modules. // This will happen in two cases: @@ -2372,13 +2460,16 @@ namespace ts { while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null const node = getNodeAtPosition(file, r.lastIndex); if (isJavaScriptFile && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) { + setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, node.arguments[0]); } - // we have to check the argument list has length of 1. We will still have to process these even though we have parsing error. - else if (isImportCall(node) && node.arguments.length === 1 && isStringLiteralLike(node.arguments[0])) { + // we have to check the argument list has length of at least 1. We will still have to process these even though we have parsing error. + else if (isImportCall(node) && node.arguments.length >= 1 && isStringLiteralLike(node.arguments[0])) { + setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, node.arguments[0]); } else if (isLiteralImportTypeNode(node)) { + setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, node.argument.literal); } } @@ -2406,7 +2497,7 @@ namespace ts { const libName = toFileNameLowerCase(ref.fileName); const libFileName = libMap.get(libName); if (libFileName) { - return getSourceFile(combinePaths(defaultLibraryPath, libFileName)); + return getSourceFile(pathForLibFile(libFileName)); } } @@ -2423,13 +2514,13 @@ namespace ts { if (hasExtension(fileName)) { const canonicalFileName = host.getCanonicalFileName(fileName); - if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule, extension => fileExtensionIs(canonicalFileName, extension))) { + if (!options.allowNonTsExtensions && !forEach(flatten(supportedExtensionsWithJsonIfResolveJsonModule), extension => fileExtensionIs(canonicalFileName, extension))) { if (fail) { if (hasJSFileExtension(canonicalFileName)) { fail(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName); } else { - fail(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'"); + fail(Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'"); } } return undefined; @@ -2461,8 +2552,9 @@ namespace ts { return undefined; } - const sourceFileWithAddedExtension = forEach(supportedExtensions, extension => getSourceFile(fileName + extension)); - if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + supportedExtensions.join("', '") + "'"); + // Only try adding extensions from the first supported group (which should be .ts/.tsx/.d.ts) + const sourceFileWithAddedExtension = forEach(supportedExtensions[0], extension => getSourceFile(fileName + extension)); + if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + flatten(supportedExtensions).join("', '") + "'"); return sourceFileWithAddedExtension; } } @@ -2616,7 +2708,7 @@ namespace ts { // We haven't looked for this file, do so now and cache result const file = host.getSourceFile( fileName, - options.target!, + getEmitScriptTarget(options), hostErrorMessage => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, Diagnostics.Cannot_read_file_0_Colon_1, [fileName, hostErrorMessage]), shouldCreateNewSourceFile ); @@ -2649,6 +2741,10 @@ namespace ts { file.path = path; file.resolvedPath = toPath(fileName); file.originalFileName = originalFileName; + // It's a _little odd_ that we can't set `impliedNodeFormat` until the program step - but it's the first and only time we have a resolution cache + // and a freshly made source file node on hand at the same time, and we need both to set the field. Persisting the resolution cache all the way + // to the check and emit steps would be bad - so we much prefer detecting and storing the format information on the source file node upfront. + file.impliedNodeFormat = getImpliedNodeFormatForFile(file.resolvedPath, moduleResolutionCache?.getPackageJsonInfoCache(), host, options); addFileIncludeReason(file, reason); if (host.useCaseSensitiveFileNames()) { @@ -2883,13 +2979,32 @@ namespace ts { } } + function pathForLibFile(libFileName: string): string { + // Support resolving to lib.dom.d.ts -> @typescript/lib-dom, and + // lib.dom.iterable.d.ts -> @typescript/lib-dom/iterable + // lib.es2015.symbol.wellknown.d.ts -> @typescript/lib-es2015/symbol-wellknown + const components = libFileName.split("."); + let path = components[1]; + let i = 2; + while (components[i] && components[i] !== "d") { + path += (i === 2 ? "/" : "-") + components[i]; + i++; + } + const resolveFrom = combinePaths(currentDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`); + const localOverrideModuleResult = resolveModuleName("@typescript/lib-" + path, resolveFrom, { moduleResolution: ModuleResolutionKind.NodeJs }, host, moduleResolutionCache); + if (localOverrideModuleResult?.resolvedModule) { + return localOverrideModuleResult.resolvedModule.resolvedFileName; + } + return combinePaths(defaultLibraryPath, libFileName); + } + function processLibReferenceDirectives(file: SourceFile) { forEach(file.libReferenceDirectives, (libReference, index) => { const libName = toFileNameLowerCase(libReference.fileName); const libFileName = libMap.get(libName); if (libFileName) { // we ignore any 'no-default-lib' reference set on this file. - processRootFile(combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }); + processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }); } else { const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts"); @@ -2919,7 +3034,7 @@ namespace ts { const optionsForFile = (useSourceOfProjectReferenceRedirect ? getRedirectReferenceForResolution(file)?.commandLine.options : undefined) || options; for (let index = 0; index < moduleNames.length; index++) { const resolution = resolutions[index]; - setResolvedModule(file, moduleNames[index], resolution); + setResolvedModule(file, moduleNames[index], resolution, getModeForResolutionAtIndex(file, index)); if (!resolution) { continue; @@ -3181,7 +3296,7 @@ namespace ts { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"); } - const languageVersion = options.target || ScriptTarget.ES3; + const languageVersion = getEmitScriptTarget(options); const firstNonAmbientExternalModuleSourceFile = find(files, f => isExternalModule(f) && !f.isDeclarationFile); if (options.isolatedModules) { @@ -3305,6 +3420,10 @@ namespace ts { } } + if (options.preserveValueImports && getEmitModuleKind(options) < ModuleKind.ES2015) { + createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later); + } + // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files if (!options.noEmit && !options.suppressOutputPathCheck) { const emitHost = getEmitHost(); @@ -3466,7 +3585,7 @@ namespace ts { message = Diagnostics.File_is_library_specified_here; break; } - const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === options.target ? key : undefined); + const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined); configFileNode = target ? getOptionsSyntaxByValue("target", target) : undefined; message = Diagnostics.File_is_default_library_for_target_specified_here; break; @@ -3575,7 +3694,7 @@ namespace ts { createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); } - function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) { + function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string) { createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0); } @@ -3590,7 +3709,7 @@ namespace ts { } } - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) { + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2); @@ -3616,7 +3735,7 @@ namespace ts { return _compilerOptionsObjectLiteralSyntax || undefined; } - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean { + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean { const props = getPropertyAssignment(objectLiteral, key1, key2); for (const prop of props) { programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2)); @@ -3656,7 +3775,7 @@ namespace ts { return containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames()); } - if (fileExtensionIsOneOf(filePath, supportedJSExtensions) || fileExtensionIs(filePath, Extension.Dts)) { + if (fileExtensionIsOneOf(filePath, supportedJSExtensionsFlat) || fileExtensionIs(filePath, Extension.Dts)) { // Otherwise just check if sourceFile with the name exists const filePathWithoutExtension = removeFileExtension(filePath); return !!getSourceFileByPath((filePathWithoutExtension + Extension.Ts) as Path) || @@ -4010,7 +4129,7 @@ namespace ts { } /* @internal */ - export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFile, index: number): StringLiteralLike { + export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFileImportsList, index: number): StringLiteralLike { if (index < imports.length) return imports[index]; let augIndex = imports.length; for (const aug of moduleAugmentations) { diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index f15cc9766d507..8c09ec3ef721d 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -5,8 +5,8 @@ namespace ts { startRecordingFilesWithChangedResolutions(): void; finishRecordingFilesWithChangedResolutions(): Path[] | undefined; - resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[]; - getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined; + resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[]; + getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined; resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[]; invalidateResolutionsOfFailedLookupLocations(): boolean; @@ -166,8 +166,8 @@ namespace ts { // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file. // The key in the map is source file's path. // The values are Map of resolutions with key being name lookedup. - const resolvedModuleNames = new Map>(); - const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); + const resolvedModuleNames = new Map>(); + const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); const nonRelativeModuleNameCache: CacheWithRedirects = createCacheWithRedirects(); const moduleResolutionCache = createModuleResolutionCache( getCurrentDirectory(), @@ -177,8 +177,8 @@ namespace ts { nonRelativeModuleNameCache, ); - const resolvedTypeReferenceDirectives = new Map>(); - const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); + const resolvedTypeReferenceDirectives = new Map>(); + const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache( getCurrentDirectory(), resolutionHost.getCanonicalFileName, @@ -354,27 +354,28 @@ namespace ts { names: readonly string[]; containingFile: string; redirectedReference: ResolvedProjectReference | undefined; - cache: ESMap>; - perDirectoryCacheWithRedirects: CacheWithRedirects>; - loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T; + cache: ESMap>; + perDirectoryCacheWithRedirects: CacheWithRedirects>; + loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile) => T; getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName; shouldRetryResolution: (t: T) => boolean; reusedNames?: readonly string[]; logChanges?: boolean; + containingSourceFile?: SourceFile; } function resolveNamesWithLocalCache({ names, containingFile, redirectedReference, cache, perDirectoryCacheWithRedirects, loader, getResolutionWithResolvedFileName, - shouldRetryResolution, reusedNames, logChanges + shouldRetryResolution, reusedNames, logChanges, containingSourceFile }: ResolveNamesWithLocalCacheInput): (R | undefined)[] { const path = resolutionHost.toPath(containingFile); - const resolutionsInFile = cache.get(path) || cache.set(path, new Map()).get(path)!; + const resolutionsInFile = cache.get(path) || cache.set(path, createModeAwareCache()).get(path)!; const dirPath = getDirectoryPath(path); const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); let perDirectoryResolution = perDirectoryCache.get(dirPath); if (!perDirectoryResolution) { - perDirectoryResolution = new Map(); + perDirectoryResolution = createModeAwareCache(); perDirectoryCache.set(dirPath, perDirectoryResolution); } const resolvedModules: (R | undefined)[] = []; @@ -388,16 +389,19 @@ namespace ts { !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path : !!redirectedReference; - const seenNamesInFile = new Map(); + const seenNamesInFile = createModeAwareCache(); + let i = 0; for (const name of names) { - let resolution = resolutionsInFile.get(name); + const mode = containingSourceFile ? getModeForResolutionAtIndex(containingSourceFile, i) : undefined; + i++; + let resolution = resolutionsInFile.get(name, mode); // Resolution is valid if it is present and not invalidated - if (!seenNamesInFile.has(name) && + if (!seenNamesInFile.has(name, mode) && unmatchedRedirects || !resolution || resolution.isInvalidated || // If the name is unresolved import that was invalidated, recalculate (hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) { const existingResolution = resolution; - const resolutionInDirectory = perDirectoryResolution.get(name); + const resolutionInDirectory = perDirectoryResolution.get(name, mode); if (resolutionInDirectory) { resolution = resolutionInDirectory; const host = resolutionHost.getCompilerHost?.() || resolutionHost; @@ -425,10 +429,10 @@ namespace ts { } } else { - resolution = loader(name, containingFile, compilerOptions, resolutionHost.getCompilerHost?.() || resolutionHost, redirectedReference); - perDirectoryResolution.set(name, resolution); + resolution = loader(name, containingFile, compilerOptions, resolutionHost.getCompilerHost?.() || resolutionHost, redirectedReference, containingSourceFile); + perDirectoryResolution.set(name, mode, resolution); } - resolutionsInFile.set(name, resolution); + resolutionsInFile.set(name, mode, resolution); watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName); if (existingResolution) { stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName); @@ -442,7 +446,7 @@ namespace ts { } else { const host = resolutionHost.getCompilerHost?.() || resolutionHost; - if (isTraceEnabled(compilerOptions, host) && !seenNamesInFile.has(name)) { + if (isTraceEnabled(compilerOptions, host) && !seenNamesInFile.has(name, mode)) { const resolved = getResolutionWithResolvedFileName(resolution); trace( host, @@ -465,15 +469,15 @@ namespace ts { } } Debug.assert(resolution !== undefined && !resolution.isInvalidated); - seenNamesInFile.set(name, true); + seenNamesInFile.set(name, mode, true); resolvedModules.push(getResolutionWithResolvedFileName(resolution)); } // Stop watching and remove the unused name - resolutionsInFile.forEach((resolution, name) => { - if (!seenNamesInFile.has(name) && !contains(reusedNames, name)) { + resolutionsInFile.forEach((resolution, name, mode) => { + if (!seenNamesInFile.has(name, mode) && !contains(reusedNames, name)) { stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName); - resolutionsInFile.delete(name); + resolutionsInFile.delete(name, mode); } }); @@ -511,7 +515,7 @@ namespace ts { }); } - function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[] { + function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference, containingSourceFile?: SourceFile): (ResolvedModuleFull | undefined)[] { return resolveNamesWithLocalCache({ names: moduleNames, containingFile, @@ -523,12 +527,14 @@ namespace ts { shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension), reusedNames, logChanges: logChangesWhenResolvingModule, + containingSourceFile, }); } - function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined { + function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): CachedResolvedModuleWithFailedLookupLocations | undefined { const cache = resolvedModuleNames.get(resolutionHost.toPath(containingFile)); - return cache && cache.get(moduleName); + if (!cache) return undefined; + return cache.get(moduleName, resolutionMode); } function isNodeModulesAtTypesDirectory(dirPath: Path) { @@ -751,7 +757,7 @@ namespace ts { } function removeResolutionsOfFileFromCache( - cache: ESMap>, + cache: ESMap>, filePath: Path, getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName, ) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 8e31a88589bf9..0c4c087e6edc5 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -83,6 +83,7 @@ namespace ts { any: SyntaxKind.AnyKeyword, as: SyntaxKind.AsKeyword, asserts: SyntaxKind.AssertsKeyword, + assert: SyntaxKind.AssertKeyword, bigint: SyntaxKind.BigIntKeyword, boolean: SyntaxKind.BooleanKeyword, break: SyntaxKind.BreakKeyword, diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index ed75cf081d9c9..e3aebc849b6a3 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -322,7 +322,8 @@ namespace ts { } // Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M]) - const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)$/; + const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; + const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/; export interface LineInfo { diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 732205c00a34b..12aeca7f67d5c 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -3,11 +3,15 @@ namespace ts { function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory { switch (moduleKind) { case ModuleKind.ESNext: + case ModuleKind.ES2022: case ModuleKind.ES2020: case ModuleKind.ES2015: return transformECMAScriptModule; case ModuleKind.System: return transformSystemModule; + case ModuleKind.Node12: + case ModuleKind.NodeNext: + return transformNodeModule; default: return transformModule; } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 935c549dbcea5..7d4afe2baffc4 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -172,7 +172,7 @@ namespace ts { function transformSourceFile(node: SourceFile) { const options = context.getCompilerOptions(); if (node.isDeclarationFile - || useDefineForClassFields && options.target === ScriptTarget.ESNext) { + || useDefineForClassFields && getEmitScriptTarget(options) === ScriptTarget.ESNext) { return node; } const visited = visitEachChild(node, visitor, context); @@ -266,15 +266,44 @@ namespace ts { /** * If we visit a private name, this means it is an undeclared private name. - * Replace it with an empty identifier to indicate a problem with the code. + * Replace it with an empty identifier to indicate a problem with the code, + * unless we are in a statement position - otherwise this will not trigger + * a SyntaxError. */ function visitPrivateIdentifier(node: PrivateIdentifier) { if (!shouldTransformPrivateElementsOrClassStaticBlocks) { return node; } + if (isStatement(node.parent)) { + return node; + } return setOriginalNode(factory.createIdentifier(""), node); } + /** + * Visits `#id in expr` + */ + function visitPrivateIdentifierInInExpression(node: BinaryExpression) { + if (!shouldTransformPrivateElementsOrClassStaticBlocks) { + return node; + } + const privId = node.left; + Debug.assertNode(privId, isPrivateIdentifier); + Debug.assert(node.operatorToken.kind === SyntaxKind.InKeyword); + const info = accessPrivateIdentifier(privId); + if (info) { + const receiver = visitNode(node.right, visitor, isExpression); + + return setOriginalNode( + context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver), + node + ); + } + + // Private name has not been declared. Subsequent transformers will handle this error + return visitEachChild(node, visitor, context); + } + /** * Visits the members of a class that has fields. * @@ -827,6 +856,9 @@ namespace ts { } } } + if (node.operatorToken.kind === SyntaxKind.InKeyword && isPrivateIdentifier(node.left)) { + return visitPrivateIdentifierInInExpression(node); + } return visitEachChild(node, visitor, context); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index e76debaa78557..6cea3b85055ee 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -732,7 +732,8 @@ namespace ts { /*decorators*/ undefined, decl.modifiers, decl.importClause, - rewriteModuleSpecifier(decl, decl.moduleSpecifier) + rewriteModuleSpecifier(decl, decl.moduleSpecifier), + /*assertClause*/ undefined ); } // The `importClause` visibility corresponds to the default's visibility. @@ -744,7 +745,7 @@ namespace ts { decl.importClause.isTypeOnly, visibleDefaultBinding, /*namedBindings*/ undefined, - ), rewriteModuleSpecifier(decl, decl.moduleSpecifier)); + ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), /*assertClause*/ undefined); } if (decl.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) { // Namespace import (optionally with visible default) @@ -754,7 +755,7 @@ namespace ts { decl.importClause.isTypeOnly, visibleDefaultBinding, namedBindings, - ), rewriteModuleSpecifier(decl, decl.moduleSpecifier)) : undefined; + ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), /*assertClause*/ undefined) : undefined; } // Named imports (optionally with visible default) const bindingList = mapDefined(decl.importClause.namedBindings.elements, b => resolver.isDeclarationVisible(b) ? b : undefined); @@ -769,7 +770,8 @@ namespace ts { visibleDefaultBinding, bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, ), - rewriteModuleSpecifier(decl, decl.moduleSpecifier) + rewriteModuleSpecifier(decl, decl.moduleSpecifier), + /*assertClause*/ undefined ); } // Augmentation of export depends on import @@ -779,7 +781,8 @@ namespace ts { /*decorators*/ undefined, decl.modifiers, /*importClause*/ undefined, - rewriteModuleSpecifier(decl, decl.moduleSpecifier) + rewriteModuleSpecifier(decl, decl.moduleSpecifier), + /*assertClause*/ undefined ); } // Nothing visible @@ -1114,6 +1117,7 @@ namespace ts { input.isTypeOnly, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier), + /*assertClause*/ undefined ); } case SyntaxKind.ExportAssignment: { @@ -1252,7 +1256,7 @@ namespace ts { /*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports(map(exportMappings, ([gen, exp]) => { - return factory.createExportSpecifier(gen, exp); + return factory.createExportSpecifier(/*isTypeOnly*/ false, gen, exp); })) )); } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 55c606f883218..ef296d779a9aa 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -56,7 +56,7 @@ namespace ts { currentFileState.utilizedImplicitRuntimeImports.set(importSource, specifierSourceImports); } const generatedName = factory.createUniqueName(`_${name}`, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel | GeneratedIdentifierFlags.AllowNameSubstitution); - const specifier = factory.createImportSpecifier(factory.createIdentifier(name), generatedName); + const specifier = factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier(name), generatedName); generatedName.generatedImportReference = specifier; specifierSourceImports.set(name, specifier); return generatedName; @@ -85,7 +85,7 @@ namespace ts { for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) { if (isExternalModule(node)) { // Add `import` statement - const importStatement = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*typeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource)); + const importStatement = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*typeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*assertClause*/ undefined); setParentRecursive(importStatement, /*incremental*/ false); statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement); } @@ -292,7 +292,7 @@ namespace ts { // When there are no attributes, React wants "null" } else { - const target = compilerOptions.target; + const target = getEmitScriptTarget(compilerOptions); if (target && target >= ScriptTarget.ES2018) { objectProperties = factory.createObjectLiteralExpression( flatten( @@ -547,7 +547,8 @@ namespace ts { } function visitJsxExpression(node: JsxExpression) { - return visitNode(node.expression, visitor, isExpression); + const expression = visitNode(node.expression, visitor, isExpression); + return node.dotDotDotToken ? factory.createSpreadElement(expression!) : expression; } } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 4a7e297722e86..5e755e5083cb3 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -5,7 +5,10 @@ namespace ts { factory, getEmitHelperFactory: emitHelpers, } = context; + const host = context.getEmitHost(); + const resolver = context.getEmitResolver(); const compilerOptions = context.getCompilerOptions(); + const languageVersion = getEmitScriptTarget(compilerOptions); const previousOnEmitNode = context.onEmitNode; const previousOnSubstituteNode = context.onSubstituteNode; context.onEmitNode = onEmitNode; @@ -14,6 +17,8 @@ namespace ts { context.enableSubstitution(SyntaxKind.Identifier); let helperNameSubstitutions: ESMap | undefined; + let currentSourceFile: SourceFile | undefined; + let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; return chainBundle(context, transformSourceFile); function transformSourceFile(node: SourceFile) { @@ -22,7 +27,16 @@ namespace ts { } if (isExternalModule(node) || compilerOptions.isolatedModules) { - const result = updateExternalModule(node); + currentSourceFile = node; + importRequireStatements = undefined; + let result = updateExternalModule(node); + currentSourceFile = undefined; + if (importRequireStatements) { + result = factory.updateSourceFile( + result, + setTextRange(factory.createNodeArray(insertStatementsAfterCustomPrologue(result.statements.slice(), importRequireStatements)), result.statements), + ); + } if (!isExternalModule(node) || some(result.statements, isExternalModuleIndicator)) { return result; } @@ -55,8 +69,10 @@ namespace ts { function visitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: - // Elide `import=` as it is not legal with --module ES6 - return undefined; + // Though an error in es2020 modules, in node-flavor es2020 modules, we can helpfully transform this to a synthetic `require` call + // To give easy access to a synchronous `require` in node-flavor esm. We do the transform even in scenarios where we error, but `import.meta.url` + // is available, just because the output is reasonable for a node-like runtime. + return getEmitScriptTarget(compilerOptions) >= ModuleKind.ES2020 ? visitImportEqualsDeclaration(node as ImportEqualsDeclaration) : undefined; case SyntaxKind.ExportAssignment: return visitExportAssignment(node as ExportAssignment); case SyntaxKind.ExportDeclaration: @@ -67,6 +83,106 @@ namespace ts { return node; } + /** + * Creates a `require()` call to import an external module. + * + * @param importNode The declaration to import. + */ + function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) { + const moduleName = getExternalModuleNameLiteral(factory, importNode, Debug.checkDefined(currentSourceFile), host, resolver, compilerOptions); + const args: Expression[] = []; + if (moduleName) { + args.push(moduleName); + } + + if (!importRequireStatements) { + const createRequireName = factory.createUniqueName("_createRequire", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel); + const importStatement = factory.createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + factory.createImportClause( + /*isTypeOnly*/ false, + /*name*/ undefined, + factory.createNamedImports([ + factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("createRequire"), createRequireName) + ]) + ), + factory.createStringLiteral("module") + ); + const requireHelperName = factory.createUniqueName("__require", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel); + const requireStatement = factory.createVariableStatement( + /*modifiers*/ undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + requireHelperName, + /*exclamationToken*/ undefined, + /*type*/ undefined, + factory.createCallExpression(factory.cloneNode(createRequireName), /*typeArguments*/ undefined, [ + factory.createPropertyAccessExpression(factory.createMetaProperty(SyntaxKind.ImportKeyword, factory.createIdentifier("meta")), factory.createIdentifier("url")) + ]) + ) + ], + /*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + ) + ); + importRequireStatements = [importStatement, requireStatement]; + + } + + const name = importRequireStatements[1].declarationList.declarations[0].name; + Debug.assertNode(name, isIdentifier); + return factory.createCallExpression(factory.cloneNode(name), /*typeArguments*/ undefined, args); + } + + /** + * Visits an ImportEqualsDeclaration node. + * + * @param node The node to visit. + */ + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); + + let statements: Statement[] | undefined; + statements = append(statements, + setOriginalNode( + setTextRange( + factory.createVariableStatement( + /*modifiers*/ undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.cloneNode(node.name), + /*exclamationToken*/ undefined, + /*type*/ undefined, + createRequireCall(node) + ) + ], + /*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None + ) + ), + node), + node + ) + ); + + statements = appendExportsOfImportEqualsDeclaration(statements, node); + + return singleOrMany(statements); + } + + function appendExportsOfImportEqualsDeclaration(statements: Statement[] | undefined, node: ImportEqualsDeclaration) { + if (hasSyntacticModifier(node, ModifierFlags.Export)) { + statements = append(statements, factory.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + node.isTypeOnly, + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, idText(node.name))]) + )); + } + return statements; + } + function visitExportAssignment(node: ExportAssignment): VisitResult { // Elide `export=` as it is not legal with --module ES6 return node.isExportEquals ? undefined : node; @@ -96,6 +212,7 @@ namespace ts { ) ), node.moduleSpecifier, + node.assertClause ); setOriginalNode(importDecl, node.exportClause); @@ -103,7 +220,7 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, /*isTypeOnly*/ false, - factory.createNamedExports([factory.createExportSpecifier(synthName, oldIdentifier)]), + factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, synthName, oldIdentifier)]), ); setOriginalNode(exportDecl, node); diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 225939a9df8a5..9c88471640956 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -556,7 +556,7 @@ namespace ts { case SyntaxKind.PartiallyEmittedExpression: return visitPartiallyEmittedExpression(node as PartiallyEmittedExpression, valueIsDiscarded); case SyntaxKind.CallExpression: - if (isImportCall(node)) { + if (isImportCall(node) && currentSourceFile.impliedNodeFormat === undefined) { return visitImportCallExpression(node); } break; @@ -814,7 +814,7 @@ namespace ts { } const promise = factory.createNewExpression(factory.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); - if (compilerOptions.esModuleInterop) { + if (getESModuleInterop(compilerOptions)) { return factory.createCallExpression(factory.createPropertyAccessExpression(promise, factory.createIdentifier("then")), /*typeArguments*/ undefined, [emitHelpers().createImportStarCallbackHelper()]); } return promise; @@ -828,7 +828,7 @@ namespace ts { // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately const promiseResolveCall = factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); let requireCall: Expression = factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); - if (compilerOptions.esModuleInterop) { + if (getESModuleInterop(compilerOptions)) { requireCall = emitHelpers().createImportStarHelper(requireCall); } @@ -864,7 +864,7 @@ namespace ts { } function getHelperExpressionForExport(node: ExportDeclaration, innerExpr: Expression) { - if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { + if (!getESModuleInterop(compilerOptions) || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { return innerExpr; } if (getExportNeedsImportStarHelper(node)) { @@ -874,7 +874,7 @@ namespace ts { } function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) { - if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { + if (!getESModuleInterop(compilerOptions) || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { return innerExpr; } if (getImportNeedsImportStarHelper(node)) { @@ -1134,7 +1134,7 @@ namespace ts { } else { const exportNeedsImportDefault = - !!compilerOptions.esModuleInterop && + !!getESModuleInterop(compilerOptions) && !(getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) && idText(specifier.propertyName || specifier.name) === "default"; const exportedValue = factory.createPropertyAccessExpression( diff --git a/src/compiler/transformers/module/node.ts b/src/compiler/transformers/module/node.ts new file mode 100644 index 0000000000000..b1addf4f3ece2 --- /dev/null +++ b/src/compiler/transformers/module/node.ts @@ -0,0 +1,84 @@ +/*@internal*/ +namespace ts { + export function transformNodeModule(context: TransformationContext) { + const previousOnSubstituteNode = context.onSubstituteNode; + const previousOnEmitNode = context.onEmitNode; + + const esmTransform = transformECMAScriptModule(context); + + const esmOnSubstituteNode = context.onSubstituteNode; + const esmOnEmitNode = context.onEmitNode; + + context.onSubstituteNode = previousOnSubstituteNode; + context.onEmitNode = previousOnEmitNode; + + const cjsTransform = transformModule(context); + + const cjsOnSubstituteNode = context.onSubstituteNode; + const cjsOnEmitNode = context.onEmitNode; + + context.onSubstituteNode = onSubstituteNode; + context.onEmitNode = onEmitNode; + context.enableSubstitution(SyntaxKind.SourceFile); + context.enableEmitNotification(SyntaxKind.SourceFile); + + let currentSourceFile: SourceFile | undefined; + return transformSourceFileOrBundle; + + function onSubstituteNode(hint: EmitHint, node: Node) { + if (isSourceFile(node)) { + currentSourceFile = node; + // Neither component transform wants substitution notifications for `SourceFile`s, and, in fact, relies on + // the source file emit notification to setup scope variables for substitutions (so we _cannot_ call their substitute + // functions on source files safely, as that context only gets setup in a later pipeline phase!) + return previousOnSubstituteNode(hint, node); + } + else { + if (!currentSourceFile) { + return previousOnSubstituteNode(hint, node); + } + if (currentSourceFile.impliedNodeFormat === ModuleKind.ESNext) { + return esmOnSubstituteNode(hint, node); + } + return cjsOnSubstituteNode(hint, node); + } + } + + function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void { + if (isSourceFile(node)) { + currentSourceFile = node; + } + if (!currentSourceFile) { + return previousOnEmitNode(hint, node, emitCallback); + } + if (currentSourceFile.impliedNodeFormat === ModuleKind.ESNext) { + return esmOnEmitNode(hint, node, emitCallback); + } + return cjsOnEmitNode(hint, node, emitCallback); + } + + function getModuleTransformForFile(file: SourceFile): (typeof esmTransform) { + return file.impliedNodeFormat === ModuleKind.ESNext ? esmTransform : cjsTransform; + } + + function transformSourceFile(node: SourceFile) { + if (node.isDeclarationFile) { + return node; + } + + currentSourceFile = node; + const result = getModuleTransformForFile(node)(node); + currentSourceFile = undefined; + Debug.assert(isSourceFile(result)); + return result; + } + + function transformSourceFileOrBundle(node: SourceFile | Bundle) { + return node.kind === SyntaxKind.SourceFile ? transformSourceFile(node) : transformBundle(node); + } + + function transformBundle(node: Bundle) { + return context.factory.createBundle(map(node.sourceFiles, transformSourceFile), node.prepends); + } + } +} diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 21a0ec59f101b..8561db1c633ef 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2507,6 +2507,7 @@ namespace ts { || (isExternalModuleExport(node) && moduleKind !== ModuleKind.ES2015 && moduleKind !== ModuleKind.ES2020 + && moduleKind !== ModuleKind.ES2022 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System); } @@ -2791,7 +2792,7 @@ namespace ts { } /** - * Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve'. + * Visits an import declaration, eliding it if it is type-only or if it has an import clause that may be elided. * * @param node The import declaration node. */ @@ -2816,50 +2817,51 @@ namespace ts { /*decorators*/ undefined, /*modifiers*/ undefined, importClause, - node.moduleSpecifier) + node.moduleSpecifier, + node.assertClause) : undefined; } /** - * Visits an import clause, eliding it if it is not referenced. + * Visits an import clause, eliding it if its `name` and `namedBindings` may both be elided. * * @param node The import clause node. */ function visitImportClause(node: ImportClause): VisitResult { - if (node.isTypeOnly) { - return undefined; - } + Debug.assert(!node.isTypeOnly); // Elide the import clause if we elide both its name and its named bindings. - const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined; + const name = shouldEmitAliasDeclaration(node) ? node.name : undefined; const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings); return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined; } /** - * Visits named import bindings, eliding it if it is not referenced. + * Visits named import bindings, eliding them if their targets, their references, and the compilation settings allow. * * @param node The named import bindings node. */ function visitNamedImportBindings(node: NamedImportBindings): VisitResult { if (node.kind === SyntaxKind.NamespaceImport) { // Elide a namespace import if it is not referenced. - return resolver.isReferencedAliasDeclaration(node) ? node : undefined; + return shouldEmitAliasDeclaration(node) ? node : undefined; } else { - // Elide named imports if all of its import specifiers are elided. + // Elide named imports if all of its import specifiers are elided and settings allow. + const allowEmpty = compilerOptions.preserveValueImports && ( + compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve || + compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error); const elements = visitNodes(node.elements, visitImportSpecifier, isImportSpecifier); - return some(elements) ? factory.updateNamedImports(node, elements) : undefined; + return allowEmpty || some(elements) ? factory.updateNamedImports(node, elements) : undefined; } } /** - * Visits an import specifier, eliding it if it is not referenced. + * Visits an import specifier, eliding it if its target, its references, and the compilation settings allow. * * @param node The import specifier node. */ function visitImportSpecifier(node: ImportSpecifier): VisitResult { - // Elide an import specifier if it is not referenced. - return resolver.isReferencedAliasDeclaration(node) ? node : undefined; + return !node.isTypeOnly && shouldEmitAliasDeclaration(node) ? node : undefined; } /** @@ -2876,8 +2878,7 @@ namespace ts { } /** - * Visits an export declaration, eliding it if it does not contain a clause that resolves - * to a value. + * Visits an export declaration, eliding it if it does not contain a clause that resolves to a value. * * @param node The export declaration node. */ @@ -2893,13 +2894,15 @@ namespace ts { return node; } - if (!resolver.isValueAliasDeclaration(node)) { - // Elide the export declaration if it does not export a value. - return undefined; - } - // Elide the export declaration if all of its named exports are elided. - const exportClause = visitNode(node.exportClause, visitNamedExportBindings, isNamedExportBindings); + const allowEmpty = !!node.moduleSpecifier && ( + compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve || + compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error); + const exportClause = visitNode( + node.exportClause, + (bindings: NamedExportBindings) => visitNamedExportBindings(bindings, allowEmpty), + isNamedExportBindings); + return exportClause ? factory.updateExportDeclaration( node, @@ -2907,7 +2910,8 @@ namespace ts { /*modifiers*/ undefined, node.isTypeOnly, exportClause, - node.moduleSpecifier) + node.moduleSpecifier, + node.assertClause) : undefined; } @@ -2917,18 +2921,18 @@ namespace ts { * * @param node The named exports node. */ - function visitNamedExports(node: NamedExports): VisitResult { + function visitNamedExports(node: NamedExports, allowEmpty: boolean): VisitResult { // Elide the named exports if all of its export specifiers were elided. const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier); - return some(elements) ? factory.updateNamedExports(node, elements) : undefined; + return allowEmpty || some(elements) ? factory.updateNamedExports(node, elements) : undefined; } function visitNamespaceExports(node: NamespaceExport): VisitResult { return factory.updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier)); } - function visitNamedExportBindings(node: NamedExportBindings): VisitResult { - return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node); + function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult { + return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node, allowEmpty); } /** @@ -2938,7 +2942,7 @@ namespace ts { */ function visitExportSpecifier(node: ExportSpecifier): VisitResult { // Elide an export specifier if it does not reference a value. - return resolver.isValueAliasDeclaration(node) ? node : undefined; + return !node.isTypeOnly && resolver.isValueAliasDeclaration(node) ? node : undefined; } /** @@ -2950,7 +2954,7 @@ namespace ts { // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when // - current file is not external module // - import declaration is top level and target is value imported by entity name - return resolver.isReferencedAliasDeclaration(node) + return shouldEmitAliasDeclaration(node) || (!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node)); } @@ -2967,7 +2971,7 @@ namespace ts { } if (isExternalModuleImportEqualsDeclaration(node)) { - const isReferenced = resolver.isReferencedAliasDeclaration(node); + const isReferenced = shouldEmitAliasDeclaration(node); // If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'. if (!isReferenced && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) { return setOriginalNode( @@ -2977,6 +2981,7 @@ namespace ts { /*modifiers*/ undefined, /*importClause*/ undefined, node.moduleReference.expression, + /*assertClause*/ undefined ), node, ), @@ -3358,5 +3363,11 @@ namespace ts { return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined; } + + function shouldEmitAliasDeclaration(node: Node): boolean { + return compilerOptions.preserveValueImports + ? resolver.isValueAliasDeclaration(node) + : resolver.isReferencedAliasDeclaration(node); + } } } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index b92741a3de8dc..ae3fd3be20d2a 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -281,9 +281,10 @@ namespace ts { const moduleResolutionCache = !compilerHost.resolveModuleNames ? createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined; const typeReferenceDirectiveResolutionCache = !compilerHost.resolveTypeReferenceDirectives ? createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache()) : undefined; if (!compilerHost.resolveModuleNames) { - const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, state.projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule!; - compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference) => - loadWithLocalCache(Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader); + const loader = (moduleName: string, resolverMode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, state.projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference, resolverMode).resolvedModule!; + compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, _options, containingSourceFile) => + loadWithModeAwareCache(Debug.checkEachDefined(moduleNames), Debug.checkDefined(containingSourceFile), containingFile, redirectedReference, loader); + compilerHost.getModuleResolutionCache = () => moduleResolutionCache; } if (!compilerHost.resolveTypeReferenceDirectives) { const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(moduleName, containingFile, state.projectCompilerOptions, compilerHost, redirectedReference, state.typeReferenceDirectiveResolutionCache).resolvedTypeReferenceDirective!; @@ -871,12 +872,12 @@ namespace ts { getConfigFileParsingDiagnostics(config), config.projectReferences ); - state.lastCachedPackageJsonLookups.set(projectPath, state.moduleResolutionCache && map( - state.moduleResolutionCache.getPackageJsonInfoCache().entries(), - ([path, data]) => ([state.host.realpath ? toPath(state, state.host.realpath(path)) : path, data] as const) - )); - if (state.watch) { + state.lastCachedPackageJsonLookups.set(projectPath, state.moduleResolutionCache && map( + state.moduleResolutionCache.getPackageJsonInfoCache().entries(), + ([path, data]) => ([state.host.realpath && data ? toPath(state, state.host.realpath(path)) : path, data] as const) + )); + state.builderPrograms.set(projectPath, program); } step++; diff --git a/src/compiler/tsconfig.json b/src/compiler/tsconfig.json index 5f118cf1e47bd..c5db068d120c1 100644 --- a/src/compiler/tsconfig.json +++ b/src/compiler/tsconfig.json @@ -63,6 +63,7 @@ "transformers/module/module.ts", "transformers/module/system.ts", "transformers/module/esnextAnd2015.ts", + "transformers/module/node.ts", "transformers/declarations/diagnostics.ts", "transformers/declarations.ts", "transformer.ts", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 55e452fb30c78..8c488241f983b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -161,6 +161,7 @@ namespace ts { AbstractKeyword, AsKeyword, AssertsKeyword, + AssertKeyword, AnyKeyword, AsyncKeyword, AwaitKeyword, @@ -341,6 +342,8 @@ namespace ts { DefaultClause, HeritageClause, CatchClause, + AssertClause, + AssertEntry, // Property assignments PropertyAssignment, @@ -544,6 +547,7 @@ namespace ts { | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword + | SyntaxKind.AssertKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword @@ -1039,6 +1043,7 @@ namespace ts { } export type AssertsKeyword = KeywordToken; + export type AssertKeyword = KeywordToken; export type AwaitKeyword = KeywordToken; /** @deprecated Use `AwaitKeyword` instead. */ @@ -1209,7 +1214,8 @@ namespace ts { readonly expression: Expression; } - export interface PrivateIdentifier extends Node { + // Typed as a PrimaryExpression due to its presence in BinaryExpressions (#field in expr) + export interface PrivateIdentifier extends PrimaryExpression { readonly kind: SyntaxKind.PrivateIdentifier; // escaping not strictly necessary // avoids gotchas in transforms and utils @@ -2598,14 +2604,14 @@ namespace ts { export interface JsxExpression extends Expression { readonly kind: SyntaxKind.JsxExpression; - readonly parent: JsxElement | JsxAttributeLike; + readonly parent: JsxElement | JsxFragment | JsxAttributeLike; readonly dotDotDotToken?: Token; readonly expression?: Expression; } export interface JsxText extends LiteralLikeNode { readonly kind: SyntaxKind.JsxText; - readonly parent: JsxElement; + readonly parent: JsxElement | JsxFragment; readonly containsOnlyTriviaWhiteSpaces: boolean; } @@ -3014,6 +3020,7 @@ namespace ts { readonly importClause?: ImportClause; /** If this is not a StringLiteral it will be a grammar error. */ readonly moduleSpecifier: Expression; + readonly assertClause?: AssertClause; } export type NamedImportBindings = @@ -3040,6 +3047,22 @@ namespace ts { readonly namedBindings?: NamedImportBindings; } + export type AssertionKey = Identifier | StringLiteral; + + export interface AssertEntry extends Node { + readonly kind: SyntaxKind.AssertEntry; + readonly parent: AssertClause; + readonly name: AssertionKey; + readonly value: StringLiteral; + } + + export interface AssertClause extends Node { + readonly kind: SyntaxKind.AssertClause; + readonly parent: ImportDeclaration | ExportDeclaration + readonly elements: NodeArray; + readonly multiLine?: boolean; + } + export interface NamespaceImport extends NamedDeclaration { readonly kind: SyntaxKind.NamespaceImport; readonly parent: ImportClause; @@ -3067,6 +3090,7 @@ namespace ts { readonly exportClause?: NamedExportBindings; /** If this is not a StringLiteral it will be a grammar error. */ readonly moduleSpecifier?: Expression; + readonly assertClause?: AssertClause; } export interface NamedImports extends Node { @@ -3088,11 +3112,13 @@ namespace ts { readonly parent: NamedImports; readonly propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) readonly name: Identifier; // Declared name + readonly isTypeOnly: boolean; } export interface ExportSpecifier extends NamedDeclaration { readonly kind: SyntaxKind.ExportSpecifier; readonly parent: NamedExports; + readonly isTypeOnly: boolean; readonly propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) readonly name: Identifier; // Declared name } @@ -3109,6 +3135,14 @@ namespace ts { | ImportOrExportSpecifier ; + export type TypeOnlyAliasDeclaration = + | ImportClause & { readonly isTypeOnly: true, readonly name: Identifier } + | ImportEqualsDeclaration & { readonly isTypeOnly: true } + | NamespaceImport & { readonly parent: ImportClause & { readonly isTypeOnly: true } } + | ImportSpecifier & { readonly parent: NamedImports & { readonly parent: ImportClause & { readonly isTypeOnly: true } } } + | ExportSpecifier & { readonly parent: NamedExports & { readonly parent: ExportDeclaration & { readonly isTypeOnly: true } } } + ; + /** * This is either an `export =` or an `export default` declaration. * Unless `isExportEquals` is set, this node was parsed as an `export default`. @@ -3552,6 +3586,20 @@ namespace ts { hasNoDefaultLib: boolean; languageVersion: ScriptTarget; + + /** + * When `module` is `Node12` or `NodeNext`, this field controls whether the + * source file in question is an ESNext-output-format file, or a CommonJS-output-format + * module. This is derived by the module resolver as it looks up the file, since + * it is derived from either the file extension of the module, or the containing + * `package.json` context, and affects both checking and emit. + * + * It is _public_ so that (pre)transformers can set this field, + * since it switches the builtin `node` module transform. Generally speaking, if unset, + * the field is treated as though it is `ModuleKind.CommonJS`. + */ + impliedNodeFormat?: ModuleKind.ESNext | ModuleKind.CommonJS; + /* @internal */ scriptKind: ScriptKind; /** @@ -3593,8 +3641,8 @@ namespace ts { // Stores a mapping 'external module reference text' -> 'resolved file name' | undefined // It is used to resolve module names in the checker. // Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead - /* @internal */ resolvedModules?: ESMap; - /* @internal */ resolvedTypeReferenceDirectiveNames: ESMap; + /* @internal */ resolvedModules?: ModeAwareCache; + /* @internal */ resolvedTypeReferenceDirectiveNames: ModeAwareCache; /* @internal */ imports: readonly StringLiteralLike[]; // Identifier only if `declare global` /* @internal */ moduleAugmentations: readonly (StringLiteral | Identifier)[]; @@ -3976,7 +4024,7 @@ namespace ts { /* @internal */ getFileIncludeReasons(): MultiMap; /* @internal */ useCaseSensitiveFileNames(): boolean; - /* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined; + /* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string, mode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations | undefined; getProjectReferences(): readonly ProjectReference[] | undefined; getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined; @@ -4363,6 +4411,7 @@ namespace ts { /* @internal */ getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): readonly TypeParameter[] | undefined; /* @internal */ isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; /* @internal */ isPropertyAccessible(node: Node, isSuper: boolean, isWrite: boolean, containingType: Type, property: Symbol): boolean; + /* @internal */ getTypeOnlyAliasDeclaration(symbol: Symbol): TypeOnlyAliasDeclaration | undefined; /* @internal */ getMemberOverrideModifierDiagnostic(node: ClassLikeDeclaration, member: ClassElement): MemberOverrideDiagnostic; } @@ -4900,7 +4949,7 @@ namespace ts { deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type deferralParent?: Type; // Source union/intersection of a deferred type cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target - typeOnlyDeclaration?: TypeOnlyCompatibleAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs + typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label accessibleChainCache?: ESMap; @@ -4934,6 +4983,7 @@ namespace ts { HasNeverType = 1 << 17, // Synthetic property with at least one never type in constituents Mapped = 1 << 18, // Property of mapped type StripOptional = 1 << 19, // Strip optionality in mapped property + Unresolved = 1 << 20, // Unresolved type alias symbol Synthetic = SyntheticProperty | SyntheticMethod, Discriminant = HasNonUniformType | HasLiteralType, Partial = ReadPartial | WritePartial @@ -5142,7 +5192,7 @@ namespace ts { IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral, // The following flags are used for different purposes during union and intersection type construction /* @internal */ - IncludesStructuredOrInstantiable = TypeParameter, + IncludesMissingType = TypeParameter, /* @internal */ IncludesNonWideningType = Index, /* @internal */ @@ -5616,8 +5666,8 @@ namespace ts { root: ConditionalRoot; checkType: Type; extendsType: Type; - resolvedTrueType: Type; - resolvedFalseType: Type; + resolvedTrueType?: Type; + resolvedFalseType?: Type; /* @internal */ resolvedInferredTrueType?: Type; // The `trueType` instantiated with the `combinedMapper`, if present /* @internal */ @@ -5938,7 +5988,13 @@ namespace ts { export enum ModuleResolutionKind { Classic = 1, - NodeJs = 2 + NodeJs = 2, + // Starting with node12, node's module resolver has significant departures from tranditional cjs resolution + // to better support ecmascript modules and their use within node - more features are still being added, so + // we can expect it to change over time, and as such, offer both a `NodeNext` moving resolution target, and a `Node12` + // version-anchored resolution target + Node12 = 3, + NodeNext = 99, // Not simply `Node12` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) } export interface PluginImport { @@ -6065,6 +6121,7 @@ namespace ts { preserveConstEnums?: boolean; noImplicitOverride?: boolean; preserveSymlinks?: boolean; + preserveValueImports?: boolean; /* @internal */ preserveWatchOutput?: boolean; project?: string; /* @internal */ pretty?: boolean; @@ -6091,7 +6148,7 @@ namespace ts { suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; /* @internal */ suppressOutputPathCheck?: boolean; - target?: ScriptTarget; // TODO: GH#18217 frequently asserted as defined + target?: ScriptTarget; traceResolution?: boolean; useUnknownInCatchVariables?: boolean; resolveJsonModule?: boolean; @@ -6143,7 +6200,12 @@ namespace ts { // module kind). ES2015 = 5, ES2020 = 6, - ESNext = 99 + ES2022 = 7, + ESNext = 99, + + // Node12+ is an amalgam of commonjs (albeit updated) and es2020+, and represents a distinct module system from es2020/esnext + Node12 = 100, + NodeNext = 199, } export const enum JsxEmit { @@ -6158,7 +6220,7 @@ namespace ts { export const enum ImportsNotUsedAsValues { Remove, Preserve, - Error + Error, } export const enum NewLineKind { @@ -6539,7 +6601,13 @@ namespace ts { Js = ".js", Jsx = ".jsx", Json = ".json", - TsBuildInfo = ".tsbuildinfo" + TsBuildInfo = ".tsbuildinfo", + Mjs = ".mjs", + Mts = ".mts", + Dmts = ".d.mts", + Cjs = ".cjs", + Cts = ".cts", + Dcts = ".d.cts", } export interface ResolvedModuleWithFailedLookupLocations { @@ -6594,7 +6662,11 @@ namespace ts { * If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just * 'throw new Error("NotImplemented")' */ - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions): (ResolvedModule | undefined)[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[]; + /** + * Returns the module resolution cache used by a provided `resolveModuleNames` implementation so that any non-name module resolution operations (eg, package.json lookup) can reuse it + */ + getModuleResolutionCache?(): ModuleResolutionCache | undefined; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ @@ -6850,7 +6922,8 @@ namespace ts { MakeTemplateObject = 1 << 18, // __makeTemplateObject (used for constructing template string array objects) ClassPrivateFieldGet = 1 << 19, // __classPrivateFieldGet (used by the class private field transformation) ClassPrivateFieldSet = 1 << 20, // __classPrivateFieldSet (used by the class private field transformation) - CreateBinding = 1 << 21, // __createBinding (use by the module transform for (re)exports and namespace imports) + ClassPrivateFieldIn = 1 << 21, // __classPrivateFieldIn (used by the class private field transformation) + CreateBinding = 1 << 22, // __createBinding (use by the module transform for (re)exports and namespace imports) FirstEmitHelper = Extends, LastEmitHelper = CreateBinding, @@ -7338,26 +7411,30 @@ namespace ts { updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration; createImportEqualsDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, name: string | Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; - createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; - updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression): ImportDeclaration; + createImportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause?: AssertClause): ImportDeclaration; + updateImportDeclaration(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause: AssertClause | undefined): ImportDeclaration; createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; + updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; + createAssertEntry(name: AssertionKey, value: StringLiteral): AssertEntry; + updateAssertEntry (node: AssertEntry, name: AssertionKey, value: StringLiteral): AssertEntry; createNamespaceImport(name: Identifier): NamespaceImport; updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport; createNamespaceExport(name: Identifier): NamespaceExport; updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport; createNamedImports(elements: readonly ImportSpecifier[]): NamedImports; updateNamedImports(node: NamedImports, elements: readonly ImportSpecifier[]): NamedImports; - createImportSpecifier(propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; - updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + createImportSpecifier(isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; + updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier): ImportSpecifier; createExportAssignment(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isExportEquals: boolean | undefined, expression: Expression): ExportAssignment; updateExportAssignment(node: ExportAssignment, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, expression: Expression): ExportAssignment; - createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression): ExportDeclaration; - updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined): ExportDeclaration; + createExportDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier?: Expression, assertClause?: AssertClause): ExportDeclaration; + updateExportDeclaration(node: ExportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, isTypeOnly: boolean, exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, assertClause: AssertClause | undefined): ExportDeclaration; createNamedExports(elements: readonly ExportSpecifier[]): NamedExports; updateNamedExports(node: NamedExports, elements: readonly ExportSpecifier[]): NamedExports; - createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; - updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; + createExportSpecifier(isTypeOnly: boolean, propertyName: string | Identifier | undefined, name: string | Identifier): ExportSpecifier; + updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier): ExportSpecifier; /* @internal*/ createMissingDeclaration(): MissingDeclaration; // @@ -8375,6 +8452,7 @@ namespace ts { ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, + ImportClauseEntries = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, @@ -8567,6 +8645,7 @@ namespace ts { readonly providePrefixAndSuffixTextForRename?: boolean; readonly includePackageJsonAutoImports?: "auto" | "on" | "off"; readonly provideRefactorNotApplicableReason?: boolean; + readonly jsxAttributeCompletionStyle?: "auto" | "braces" | "none"; } /** Represents a bigint literal value without requiring bigint support */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a96753dcf0812..f93498f8ec7a0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -169,24 +169,24 @@ namespace ts { return node.end - node.pos; } - export function getResolvedModule(sourceFile: SourceFile | undefined, moduleNameText: string): ResolvedModuleFull | undefined { - return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText); + export function getResolvedModule(sourceFile: SourceFile | undefined, moduleNameText: string, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): ResolvedModuleFull | undefined { + return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText, mode); } - export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void { + export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull, mode: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): void { if (!sourceFile.resolvedModules) { - sourceFile.resolvedModules = new Map(); + sourceFile.resolvedModules = createModeAwareCache(); } - sourceFile.resolvedModules.set(moduleNameText, resolvedModule); + sourceFile.resolvedModules.set(moduleNameText, mode, resolvedModule); } export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective): void { if (!sourceFile.resolvedTypeReferenceDirectiveNames) { - sourceFile.resolvedTypeReferenceDirectiveNames = new Map(); + sourceFile.resolvedTypeReferenceDirectiveNames = createModeAwareCache(); } - sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); + sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, /*mode*/ undefined, resolvedTypeReferenceDirective); } export function projectReferenceIsEqualTo(oldRef: ProjectReference, newRef: ProjectReference) { @@ -221,13 +221,14 @@ namespace ts { export function hasChangesInResolutions( names: readonly string[], newResolutions: readonly T[], - oldResolutions: ReadonlyESMap | undefined, + oldResolutions: ModeAwareCache | undefined, + oldSourceFile: SourceFile | undefined, comparer: (oldResolution: T, newResolution: T) => boolean): boolean { Debug.assert(names.length === newResolutions.length); for (let i = 0; i < names.length; i++) { const newResolution = newResolutions[i]; - const oldResolution = oldResolutions && oldResolutions.get(names[i]); + const oldResolution = oldResolutions && oldResolutions.get(names[i], oldSourceFile && getModeForResolutionAtIndex(oldSourceFile, i)); const changed = oldResolution ? !newResolution || !comparer(oldResolution, newResolution) @@ -791,8 +792,12 @@ namespace ts { return symbol.declarations?.find(d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d))); } + function isCommonJSContainingModuleKind(kind: ModuleKind) { + return kind === ModuleKind.CommonJS || kind === ModuleKind.Node12 || kind === ModuleKind.NodeNext; + } + export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { - return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator); + return isExternalModule(node) || compilerOptions.isolatedModules || (isCommonJSContainingModuleKind(getEmitModuleKind(compilerOptions)) && !!node.commonJsModuleIndicator); } /** @@ -1949,6 +1954,8 @@ namespace ts { node = node.parent; } return node.parent.kind === SyntaxKind.TypeQuery || isJSDocLinkLike(node.parent) || isJSDocNameReference(node.parent) || isJSDocMemberName(node.parent) || isJSXTagName(node); + case SyntaxKind.PrivateIdentifier: + return isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === SyntaxKind.InKeyword; case SyntaxKind.Identifier: if (node.parent.kind === SyntaxKind.TypeQuery || isJSDocLinkLike(node.parent) || isJSDocNameReference(node.parent) || isJSDocMemberName(node.parent) || isJSXTagName(node)) { return true; @@ -2723,6 +2730,18 @@ namespace ts { return parameter && parameter.symbol; } + export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag) { + if (isJSDoc(node.parent) && node.parent.tags) { + // A @template tag belongs to any @typedef, @callback, or @enum tags in the same comment block, if they exist. + const typeAlias = find(node.parent.tags, isJSDocTypeAlias); + if (typeAlias) { + return typeAlias; + } + } + // otherwise it belongs to the host it annotates + return getHostSignatureFromJSDoc(node); + } + export function getHostSignatureFromJSDoc(node: Node): SignatureDeclaration | undefined { const host = getEffectiveJSDocHost(node); return host && isFunctionLike(host) ? host : undefined; @@ -3694,6 +3713,7 @@ namespace ts { case SyntaxKind.ThisKeyword: case SyntaxKind.SuperKeyword: case SyntaxKind.Identifier: + case SyntaxKind.PrivateIdentifier: case SyntaxKind.NullKeyword: case SyntaxKind.TrueKeyword: case SyntaxKind.FalseKeyword: @@ -4258,7 +4278,15 @@ namespace ts { const path = outputDir ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName) : fileName; - return removeFileExtension(path) + Extension.Dts; + const declarationExtension = getDeclarationEmitExtensionForPath(path); + return removeFileExtension(path) + declarationExtension; + } + + export function getDeclarationEmitExtensionForPath(path: string) { + return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : + fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : + fileExtensionIsOneOf(path, [Extension.Json]) ? `.json.d.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well + Extension.Dts; } export function outFile(options: CompilerOptions) { @@ -6098,8 +6126,11 @@ namespace ts { return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; } - export function getEmitScriptTarget(compilerOptions: CompilerOptions) { - return compilerOptions.target || ScriptTarget.ES3; + export function getEmitScriptTarget(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}) { + return compilerOptions.target || + (compilerOptions.module === ModuleKind.Node12 && ScriptTarget.ES2020) || + (compilerOptions.module === ModuleKind.NodeNext && ScriptTarget.ESNext) || + ScriptTarget.ES3; } export function getEmitModuleKind(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}) { @@ -6111,7 +6142,20 @@ namespace ts { export function getEmitModuleResolutionKind(compilerOptions: CompilerOptions) { let moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { - moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic; + switch (getEmitModuleKind(compilerOptions)) { + case ModuleKind.CommonJS: + moduleResolution = ModuleResolutionKind.NodeJs; + break; + case ModuleKind.Node12: + moduleResolution = ModuleResolutionKind.Node12; + break; + case ModuleKind.NodeNext: + moduleResolution = ModuleResolutionKind.NodeNext; + break; + default: + moduleResolution = ModuleResolutionKind.Classic; + break; + } } return moduleResolution; } @@ -6122,6 +6166,7 @@ namespace ts { case ModuleKind.AMD: case ModuleKind.ES2015: case ModuleKind.ES2020: + case ModuleKind.ES2022: case ModuleKind.ESNext: return true; default: @@ -6141,11 +6186,23 @@ namespace ts { return !!(getEmitDeclarations(options) && options.declarationMap); } + export function getESModuleInterop(compilerOptions: CompilerOptions) { + if (compilerOptions.esModuleInterop !== undefined) { + return compilerOptions.esModuleInterop; + } + switch (getEmitModuleKind(compilerOptions)) { + case ModuleKind.Node12: + case ModuleKind.NodeNext: + return true; + } + return undefined; + } + export function getAllowSyntheticDefaultImports(compilerOptions: CompilerOptions) { const moduleKind = getEmitModuleKind(compilerOptions); return compilerOptions.allowSyntheticDefaultImports !== undefined ? compilerOptions.allowSyntheticDefaultImports - : compilerOptions.esModuleInterop || + : getESModuleInterop(compilerOptions) || moduleKind === ModuleKind.System; } @@ -6181,7 +6238,7 @@ namespace ts { } export function getUseDefineForClassFields(compilerOptions: CompilerOptions): boolean { - return compilerOptions.useDefineForClassFields === undefined ? compilerOptions.target === ScriptTarget.ESNext : compilerOptions.useDefineForClassFields; + return compilerOptions.useDefineForClassFields === undefined ? getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext : compilerOptions.useDefineForClassFields; } export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean { @@ -6325,9 +6382,12 @@ namespace ts { const aParts = getPathComponents(getNormalizedAbsolutePath(a, cwd)); const bParts = getPathComponents(getNormalizedAbsolutePath(b, cwd)); let isDirectory = false; - while (!isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) && + while ( + aParts.length >= 2 && bParts.length >= 2 && + !isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) && !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) && - getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1])) { + getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1]) + ) { aParts.pop(); bParts.pop(); isDirectory = true; @@ -6337,8 +6397,8 @@ namespace ts { // KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink. // ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked. - function isNodeModulesOrScopedPackageDirectory(s: string, getCanonicalFileName: GetCanonicalFileName): boolean { - return getCanonicalFileName(s) === "node_modules" || startsWith(s, "@"); + function isNodeModulesOrScopedPackageDirectory(s: string | undefined, getCanonicalFileName: GetCanonicalFileName): boolean { + return s !== undefined && (getCanonicalFileName(s) === "node_modules" || startsWith(s, "@")); } function stripLeadingDirectorySeparator(s: string): string | undefined { @@ -6698,39 +6758,44 @@ namespace ts { } /** - * List of supported extensions in order of file resolution precedence. + * Groups of supported extensions in order of file resolution precedence. (eg, TS > TSX > DTS and seperately, CTS > DCTS) */ - export const supportedTSExtensions: readonly Extension[] = [Extension.Ts, Extension.Tsx, Extension.Dts]; - export const supportedTSExtensionsWithJson: readonly Extension[] = [Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Json]; + export const supportedTSExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts], [Extension.Cts, Extension.Dcts], [Extension.Mts, Extension.Dmts]]; + export const supportedTSExtensionsFlat: readonly Extension[] = flatten(supportedTSExtensions); + const supportedTSExtensionsWithJson: readonly Extension[][] = [...supportedTSExtensions, [Extension.Json]]; /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ - export const supportedTSExtensionsForExtractExtension: readonly Extension[] = [Extension.Dts, Extension.Ts, Extension.Tsx]; - export const supportedJSExtensions: readonly Extension[] = [Extension.Js, Extension.Jsx]; - export const supportedJSAndJsonExtensions: readonly Extension[] = [Extension.Js, Extension.Jsx, Extension.Json]; - const allSupportedExtensions: readonly Extension[] = [...supportedTSExtensions, ...supportedJSExtensions]; - const allSupportedExtensionsWithJson: readonly Extension[] = [...supportedTSExtensions, ...supportedJSExtensions, Extension.Json]; - - export function getSupportedExtensions(options?: CompilerOptions): readonly Extension[]; - export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[]; - export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[] { + const supportedTSExtensionsForExtractExtension: readonly Extension[] = [Extension.Dts, Extension.Dcts, Extension.Dmts, Extension.Cts, Extension.Mts, Extension.Ts, Extension.Tsx, Extension.Cts, Extension.Mts]; + export const supportedJSExtensions: readonly Extension[][] = [[Extension.Js, Extension.Jsx], [Extension.Mjs], [Extension.Cjs]]; + export const supportedJSExtensionsFlat: readonly Extension[] = flatten(supportedJSExtensions); + const allSupportedExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Js, Extension.Jsx], [Extension.Cts, Extension.Dcts, Extension.Cjs], [Extension.Mts, Extension.Dmts, Extension.Mjs]]; + const allSupportedExtensionsWithJson: readonly Extension[][] = [...allSupportedExtensions, [Extension.Json]]; + + export function getSupportedExtensions(options?: CompilerOptions): readonly Extension[][]; + export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][]; + export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): readonly string[][] { const needJsExtensions = options && getAllowJSCompilerOption(options); if (!extraFileExtensions || extraFileExtensions.length === 0) { return needJsExtensions ? allSupportedExtensions : supportedTSExtensions; } + const builtins = needJsExtensions ? allSupportedExtensions : supportedTSExtensions; + const flatBuiltins = flatten(builtins); const extensions = [ - ...needJsExtensions ? allSupportedExtensions : supportedTSExtensions, - ...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJSLike(x.scriptKind) ? x.extension : undefined) + ...builtins, + ...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJSLike(x.scriptKind) && flatBuiltins.indexOf(x.extension as Extension) === -1 ? [x.extension] : undefined) ]; - return deduplicate(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive); + return extensions; } - export function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[]): readonly string[] { + export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly Extension[][]): readonly Extension[][]; + export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][]; + export function getSupportedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: readonly string[][]): readonly string[][] { if (!options || !options.resolveJsonModule) return supportedExtensions; if (supportedExtensions === allSupportedExtensions) return allSupportedExtensionsWithJson; if (supportedExtensions === supportedTSExtensions) return supportedTSExtensionsWithJson; - return [...supportedExtensions, Extension.Json]; + return [...supportedExtensions, [Extension.Json]]; } function isJSLike(scriptKind: ScriptKind | undefined): boolean { @@ -6738,18 +6803,18 @@ namespace ts { } export function hasJSFileExtension(fileName: string): boolean { - return some(supportedJSExtensions, extension => fileExtensionIs(fileName, extension)); + return some(supportedJSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); } export function hasTSFileExtension(fileName: string): boolean { - return some(supportedTSExtensions, extension => fileExtensionIs(fileName, extension)); + return some(supportedTSExtensionsFlat, extension => fileExtensionIs(fileName, extension)); } export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { if (!fileName) return false; const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); - for (const extension of getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions)) { + for (const extension of flatten(getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions))) { if (fileExtensionIs(fileName, extension)) { return true; } @@ -6769,59 +6834,7 @@ namespace ts { ); } - /** - * Extension boundaries by priority. Lower numbers indicate higher priorities, and are - * aligned to the offset of the highest priority extension in the - * allSupportedExtensions array. - */ - export const enum ExtensionPriority { - TypeScriptFiles = 0, - DeclarationAndJavaScriptFiles = 2, - - Highest = TypeScriptFiles, - Lowest = DeclarationAndJavaScriptFiles, - } - - export function getExtensionPriority(path: string, supportedExtensions: readonly string[]): ExtensionPriority { - for (let i = supportedExtensions.length - 1; i >= 0; i--) { - if (fileExtensionIs(path, supportedExtensions[i])) { - return adjustExtensionPriority(i as ExtensionPriority, supportedExtensions); - } - } - - // If its not in the list of supported extensions, this is likely a - // TypeScript file with a non-ts extension - return ExtensionPriority.Highest; - } - - /** - * Adjusts an extension priority to be the highest priority within the same range. - */ - export function adjustExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: readonly string[]): ExtensionPriority { - if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) { - return ExtensionPriority.TypeScriptFiles; - } - else if (extensionPriority < supportedExtensions.length) { - return ExtensionPriority.DeclarationAndJavaScriptFiles; - } - else { - return supportedExtensions.length; - } - } - - /** - * Gets the next lowest extension priority for a given priority. - */ - export function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: readonly string[]): ExtensionPriority { - if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) { - return ExtensionPriority.DeclarationAndJavaScriptFiles; - } - else { - return supportedExtensions.length; - } - } - - const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; + const extensionsToRemove = [Extension.Dts, Extension.Dmts, Extension.Dcts, Extension.Mjs, Extension.Mts, Extension.Cjs, Extension.Cts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; export function removeFileExtension(path: string): string { for (const ext of extensionsToRemove) { const extensionless = tryRemoveExtension(path, ext); @@ -6873,7 +6886,7 @@ namespace ts { /** True if an extension is one of the supported TypeScript extensions. */ export function extensionIsTS(ext: Extension): boolean { - return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts; + return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts || ext === Extension.Cts || ext === Extension.Mts || ext === Extension.Dmts || ext === Extension.Dcts; } export function resolutionExtensionIsTSOrJson(ext: Extension) { @@ -7086,10 +7099,6 @@ namespace ts { || !(isExpressionNode(useSite) || isShorthandPropertyNameUseSite(useSite)); } - export function typeOnlyDeclarationIsExport(typeOnlyDeclaration: Node) { - return typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier; - } - function isShorthandPropertyNameUseSite(useSite: Node) { return isIdentifier(useSite) && isShorthandPropertyAssignment(useSite.parent) && useSite.parent.name === useSite; } @@ -7397,4 +7406,17 @@ namespace ts { export function isInfinityOrNaNString(name: string | __String): boolean { return name === "Infinity" || name === "-Infinity" || name === "NaN"; } + + export function isCatchClauseVariableDeclaration(node: Node) { + return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause; + } + + export function isParameterOrCatchClauseVariable(symbol: Symbol) { + const declaration = symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration); + return !!declaration && (isParameter(declaration) || isCatchClauseVariableDeclaration(declaration)); + } + + export function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction { + return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction; + } } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index b9236521cba67..d638ec32a8270 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -11,7 +11,7 @@ namespace ts { } export function getDefaultLibFileName(options: CompilerOptions): string { - switch (options.target) { + switch (getEmitScriptTarget(options)) { case ScriptTarget.ESNext: return "lib.esnext.full.d.ts"; case ScriptTarget.ES2021: @@ -1126,11 +1126,11 @@ namespace ts { return isImportSpecifier(node) || isExportSpecifier(node); } - export function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyCompatibleAliasDeclaration { + export function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyAliasDeclaration { switch (node.kind) { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - return (node as ImportOrExportSpecifier).parent.parent.isTypeOnly; + return (node as ImportOrExportSpecifier).isTypeOnly || (node as ImportOrExportSpecifier).parent.parent.isTypeOnly; case SyntaxKind.NamespaceImport: return (node as NamespaceImport).parent.isTypeOnly; case SyntaxKind.ImportClause: @@ -1141,6 +1141,10 @@ namespace ts { } } + export function isAssertionKey(node: Node): node is AssertionKey { + return isStringLiteral(node) || isIdentifier(node); + } + export function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken { return node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind); } @@ -1512,6 +1516,7 @@ namespace ts { case SyntaxKind.ClassExpression: case SyntaxKind.FunctionExpression: case SyntaxKind.Identifier: + case SyntaxKind.PrivateIdentifier: // technically this is only an Expression if it's in a `#field in expr` BinaryExpression case SyntaxKind.RegularExpressionLiteral: case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 94ab1afbb8aa0..869d4604bd037 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1076,7 +1076,20 @@ namespace ts { nodesVisitor(node.decorators, visitor, isDecorator), nodesVisitor(node.modifiers, visitor, isModifier), nodeVisitor(node.importClause, visitor, isImportClause), - nodeVisitor(node.moduleSpecifier, visitor, isExpression)); + nodeVisitor(node.moduleSpecifier, visitor, isExpression), + nodeVisitor(node.assertClause, visitor, isAssertClause)); + + case SyntaxKind.AssertClause: + Debug.type(node); + return factory.updateAssertClause(node, + nodesVisitor(node.elements, visitor, isAssertEntry), + node.multiLine); + + case SyntaxKind.AssertEntry: + Debug.type(node); + return factory.updateAssertEntry(node, + nodeVisitor(node.name, visitor, isAssertionKey), + nodeVisitor(node.value, visitor, isStringLiteral)); case SyntaxKind.ImportClause: Debug.type(node); @@ -1103,6 +1116,7 @@ namespace ts { case SyntaxKind.ImportSpecifier: Debug.type(node); return factory.updateImportSpecifier(node, + node.isTypeOnly, nodeVisitor(node.propertyName, visitor, isIdentifier), nodeVisitor(node.name, visitor, isIdentifier)); @@ -1120,7 +1134,8 @@ namespace ts { nodesVisitor(node.modifiers, visitor, isModifier), node.isTypeOnly, nodeVisitor(node.exportClause, visitor, isNamedExportBindings), - nodeVisitor(node.moduleSpecifier, visitor, isExpression)); + nodeVisitor(node.moduleSpecifier, visitor, isExpression), + nodeVisitor(node.assertClause, visitor, isAssertClause)); case SyntaxKind.NamedExports: Debug.type(node); @@ -1130,6 +1145,7 @@ namespace ts { case SyntaxKind.ExportSpecifier: Debug.type(node); return factory.updateExportSpecifier(node, + node.isTypeOnly, nodeVisitor(node.propertyName, visitor, isIdentifier), nodeVisitor(node.name, visitor, isIdentifier)); diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 3f63422a7fa16..71853f4f34b52 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -279,7 +279,7 @@ namespace ts { ); case FileIncludeKind.LibFile: if (reason.index !== undefined) return chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Library_0_specified_in_compilerOptions, options.lib![reason.index]); - const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === options.target ? key : undefined); + const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined); return chainDiagnosticMessages( /*details*/ undefined, target ? diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 1cc21a0bc9400..4b1eba91b7cdc 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -101,7 +101,7 @@ namespace ts { getEnvironmentVariable?(name: string): string | undefined; /** If provided, used to resolve the module names, otherwise typescript's default module resolution */ - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions): (ResolvedModule | undefined)[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile?: SourceFile): (ResolvedModule | undefined)[]; /** If provided, used to resolve type reference directives, otherwise typescript's default resolution */ resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions): (ResolvedTypeReferenceDirective | undefined)[]; } @@ -349,7 +349,7 @@ namespace ts { // Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names compilerHost.resolveModuleNames = host.resolveModuleNames ? ((...args) => host.resolveModuleNames!(...args)) : - ((moduleNames, containingFile, reusedNames, redirectedReference) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference)); + ((moduleNames, containingFile, reusedNames, redirectedReference, _options, sourceFile) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, sourceFile)); compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ? ((...args) => host.resolveTypeReferenceDirectives!(...args)) : ((typeDirectiveNames, containingFile, redirectedReference) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference)); diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index aac36908badb2..c6b9df2c3e3b5 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -499,7 +499,7 @@ namespace ts { // If its declaration directory: its not ignored if not excluded by config if (options.declarationDir) return false; } - else if (!fileExtensionIsOneOf(fileOrDirectoryPath, supportedJSExtensions)) { + else if (!fileExtensionIsOneOf(fileOrDirectoryPath, supportedJSExtensionsFlat)) { return false; } diff --git a/src/deprecatedCompat/deprecations.ts b/src/deprecatedCompat/deprecations.ts index a70db0d344298..292840166b36f 100644 --- a/src/deprecatedCompat/deprecations.ts +++ b/src/deprecatedCompat/deprecations.ts @@ -1224,7 +1224,7 @@ namespace ts { exportClause: NamedExportBindings | undefined, moduleSpecifier: Expression | undefined, isTypeOnly: boolean) { - return factory.updateExportDeclaration(node, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier); + return factory.updateExportDeclaration(node, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, node.assertClause); }, factoryDeprecation); /** @deprecated Use `factory.createJSDocParameterTag` or the factory supplied by your transformation context instead. */ diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index 87084d4f4bb75..54e15e1fb37b0 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -43,10 +43,10 @@ namespace ts { } const path = file.path; - if (fileExtensionIsOneOf(path, supportedTSExtensions)) { + if (fileExtensionIsOneOf(path, supportedTSExtensionsFlat)) { return "TypeScript"; } - else if (fileExtensionIsOneOf(path, supportedJSExtensions)) { + else if (fileExtensionIsOneOf(path, supportedJSExtensionsFlat)) { return "JavaScript"; } else if (fileExtensionIs(path, Extension.Json)) { @@ -354,7 +354,7 @@ namespace ts { function printEasyHelp(sys: System, simpleOptions: readonly CommandLineOption[]) { const colors = createColors(sys); - let output: string[] = [...getHelpHeader(sys)]; + let output: string[] = [...getHeader(sys,`${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)]; output.push(colors.bold(getDiagnosticText(Diagnostics.COMMON_COMMANDS)) + sys.newLine + sys.newLine); example("tsc", Diagnostics.Compiles_the_current_project_tsconfig_json_in_the_working_directory); @@ -388,7 +388,7 @@ namespace ts { } function printAllHelp(sys: System, compilerOptions: readonly CommandLineOption[], buildOptions: readonly CommandLineOption[], watchOptions: readonly CommandLineOption[]) { - let output: string[] = [...getHelpHeader(sys)]; + let output: string[] = [...getHeader(sys,`${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)]; output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.ALL_COMPILER_OPTIONS), compilerOptions, /*subCategory*/ true, /* beforeOptionsDescription */ undefined, formatMessage(/*_dummy*/ undefined, Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsconfig-reference"))]; output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.WATCH_OPTIONS), watchOptions, /*subCategory*/ false, getDiagnosticText(Diagnostics.Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_config_watch_mode_with_Colon))]; output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(/*_dummy*/ undefined, Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; @@ -398,32 +398,31 @@ namespace ts { } function printBuildHelp(sys: System, buildOptions: readonly CommandLineOption[]) { - let output: string[] = [...getHelpHeader(sys)]; + let output: string[] = [...getHeader(sys,`${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)]; output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(/*_dummy*/ undefined, Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; for (const line of output) { sys.write(line); } } - function getHelpHeader(sys: System) { + function getHeader(sys: System, message: string) { const colors = createColors(sys); const header: string[] = []; - const tscExplanation = `${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`; const terminalWidth = sys.getWidthOfTerminal?.() ?? 0;; const tsIconLength = 5; const tsIconFirstLine = colors.blueBackground(padLeft("", tsIconLength)); const tsIconSecondLine = colors.blueBackground(colors.brightWhite(padLeft("TS ", tsIconLength))); // If we have enough space, print TS icon. - if (terminalWidth >= tscExplanation.length + tsIconLength) { + if (terminalWidth >= message.length + tsIconLength) { // right align of the icon is 120 at most. const rightAlign = terminalWidth > 120 ? 120 : terminalWidth; const leftAlign = rightAlign - tsIconLength; - header.push(padRight(tscExplanation, leftAlign) + tsIconFirstLine + sys.newLine); + header.push(padRight(message, leftAlign) + tsIconFirstLine + sys.newLine); header.push(padLeft("", leftAlign) + tsIconSecondLine + sys.newLine); } else { - header.push(tscExplanation + sys.newLine); + header.push(message + sys.newLine); header.push(sys.newLine); } return header; @@ -1035,7 +1034,12 @@ namespace ts { } else { sys.writeFile(file, generateTSConfig(options, fileNames, sys.newLine)); - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file)); + const output: string[] = [sys.newLine, ...getHeader(sys,"Created a new tsconfig.json with:")]; + output.push(getCompilerOptionsDiffValue(options, sys.newLine) + sys.newLine + sys.newLine); + output.push(`You can learn more at https://aka.ms/tsconfig.json` + sys.newLine); + for (const line of output) { + sys.write(line); + } } return; diff --git a/src/harness/compilerImpl.ts b/src/harness/compilerImpl.ts index 41003356fc23a..40e3994b1c9bd 100644 --- a/src/harness/compilerImpl.ts +++ b/src/harness/compilerImpl.ts @@ -118,11 +118,11 @@ namespace compiler { const input = new documents.TextDocument(sourceFile.fileName, sourceFile.text); this._inputs.push(input); if (!vpath.isDeclaration(sourceFile.fileName)) { - const extname = ts.getOutputExtension(sourceFile, this.options); + const extname = ts.getOutputExtension(sourceFile.fileName, this.options); const outputs: CompilationOutput = { inputs: [input], js: js.get(this.getOutputPath(sourceFile.fileName, extname)), - dts: dts.get(this.getOutputPath(sourceFile.fileName, ".d.ts")), + dts: dts.get(this.getOutputPath(sourceFile.fileName, ts.getDeclarationEmitExtensionForPath(sourceFile.fileName))), map: maps.get(this.getOutputPath(sourceFile.fileName, extname + ".map")) }; @@ -205,7 +205,7 @@ namespace compiler { } else { path = vpath.resolve(this.vfs.cwd(), path); - const outDir = ext === ".d.ts" ? this.options.declarationDir || this.options.outDir : this.options.outDir; + const outDir = ext === ".d.ts" || ext === ".json.d.ts" || ext === ".d.mts" || ext === ".d.cts" ? this.options.declarationDir || this.options.outDir : this.options.outDir; if (outDir) { const common = this.commonSourceDirectory; if (common) { @@ -249,7 +249,7 @@ namespace compiler { } // establish defaults (aligns with old harness) - if (compilerOptions.target === undefined) compilerOptions.target = ts.ScriptTarget.ES3; + if (compilerOptions.target === undefined && compilerOptions.module !== ts.ModuleKind.Node12 && compilerOptions.module !== ts.ModuleKind.NodeNext) compilerOptions.target = ts.ScriptTarget.ES3; if (compilerOptions.newLine === undefined) compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed; if (compilerOptions.skipDefaultLibCheck === undefined) compilerOptions.skipDefaultLibCheck = true; if (compilerOptions.noErrorTruncation === undefined) compilerOptions.noErrorTruncation = true; @@ -264,7 +264,9 @@ namespace compiler { const program = ts.createProgram(rootFiles || [], compilerOptions, host); const emitResult = program.emit(); const postErrors = ts.getPreEmitDiagnostics(program); - const errors = preErrors && (preErrors.length !== postErrors.length) ? [...postErrors, + const longerErrors = ts.length(preErrors) > postErrors.length ? preErrors : postErrors; + const shorterErrors = longerErrors === preErrors ? postErrors : preErrors; + const errors = preErrors && (preErrors.length !== postErrors.length) ? [...shorterErrors!, ts.addRelatedInfo( ts.createCompilerDiagnostic({ category: ts.DiagnosticCategory.Error, @@ -278,7 +280,7 @@ namespace compiler { key: "-1", message: `The excess diagnostics are:` }), - ...ts.filter(postErrors, p => !ts.some(preErrors, p2 => ts.compareDiagnostics(p, p2) === ts.Comparison.EqualTo)) + ...ts.filter(longerErrors!, p => !ts.some(shorterErrors, p2 => ts.compareDiagnostics(p, p2) === ts.Comparison.EqualTo)) ) ] : postErrors; return new CompilationResult(host, compilerOptions, program, emitResult, errors); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 9e4db5e973b1d..01f8113efe122 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -313,12 +313,13 @@ namespace FourSlash { this.addMatchedInputFile(referenceFilePath, /* extensions */ undefined); }); + const exts = ts.flatten(ts.getSupportedExtensions(compilationOptions)); // Add import files into language-service host ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison const importedFilePath = this.basePath + "/" + importedFile.fileName; - this.addMatchedInputFile(importedFilePath, ts.getSupportedExtensions(compilationOptions)); + this.addMatchedInputFile(importedFilePath, exts); }); // Check if no-default-lib flag is false and if so add default library @@ -636,7 +637,8 @@ namespace FourSlash { ts.forEachKey(this.inputFiles, fileName => { if (!ts.isAnySupportedFileExtension(fileName) || Harness.getConfigNameFromFileName(fileName) - || !ts.getAllowJSCompilerOption(this.getProgram().getCompilerOptions()) && !ts.resolutionExtensionIsTSOrJson(ts.extensionFromPath(fileName))) return; + || !ts.getAllowJSCompilerOption(this.getProgram().getCompilerOptions()) && !ts.resolutionExtensionIsTSOrJson(ts.extensionFromPath(fileName)) + || ts.getBaseFileName(fileName) === "package.json") return; const errors = this.getDiagnostics(fileName).filter(e => e.category !== ts.DiagnosticCategory.Suggestion); if (errors.length) { this.printErrorLog(/*expectErrors*/ false, errors); @@ -1244,20 +1246,6 @@ namespace FourSlash { } } - public verifyNoReferences(markerNameOrRange?: string | Range) { - if (markerNameOrRange !== undefined) this.goToMarkerOrRange(markerNameOrRange); - const refs = this.getReferencesAtCaret(); - if (refs && refs.length) { - this.raiseError(`Expected getReferences to fail, but saw references: ${stringify(refs)}`); - } - } - - /** @deprecated - use `verify.baselineFindAllReferences()` instead. */ - public verifyGetReferencesForServerTest(expected: readonly ts.ReferenceEntry[]): void { - const refs = this.getReferencesAtCaret(); - assert.deepEqual(refs, expected); - } - public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[] | string) { ranges = ts.isString(ranges) ? this.rangesByText().get(ranges)! : ranges || this.getRanges(); this.verifyReferenceGroups(ranges, [{ definition, ranges }]); @@ -1338,10 +1326,6 @@ namespace FourSlash { return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source, preferences, data); } - private getReferencesAtCaret() { - return this.languageService.getReferencesAtPosition(this.activeFile.fileName, this.currentCaretPosition); - } - private findReferencesAtCaret() { return this.languageService.findReferences(this.activeFile.fileName, this.currentCaretPosition); } @@ -1927,7 +1911,7 @@ namespace FourSlash { } public baselineSyntacticAndSemanticDiagnostics() { - const files = this.getCompilerTestFiles(); + const files = ts.filter(this.getCompilerTestFiles(), f => !ts.endsWith(f.unitName, ".json")); const result = this.getSyntacticDiagnosticBaselineText(files) + Harness.IO.newLine() + Harness.IO.newLine() diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 7479d2258c43d..69f9679add0f6 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -356,18 +356,6 @@ namespace FourSlashInterface { this.state.verifyBaselineGetFileReferences(fileName); } - public referenceGroups(starts: ArrayOrSingle | ArrayOrSingle, parts: ReferenceGroup[]) { - this.state.verifyReferenceGroups(starts, parts); - } - - public noReferences(markerNameOrRange?: string | FourSlash.Range) { - this.state.verifyNoReferences(markerNameOrRange); - } - - public getReferencesForServerTest(expected: readonly ts.ReferenceEntry[]) { - this.state.verifyGetReferencesForServerTest(expected); - } - public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[] | string) { this.state.verifySingleReferenceGroup(definition, ranges); } @@ -1061,6 +1049,8 @@ namespace FourSlashInterface { interfaceEntry("NumberConstructor"), interfaceEntry("TemplateStringsArray"), interfaceEntry("ImportMeta"), + interfaceEntry("ImportCallOptions"), + interfaceEntry("ImportAssertions"), varEntry("Math"), varEntry("Date"), interfaceEntry("DateConstructor"), @@ -1095,6 +1085,7 @@ namespace FourSlashInterface { typeEntry("PromiseConstructorLike"), interfaceEntry("PromiseLike"), interfaceEntry("Promise"), + typeEntry("Awaited"), interfaceEntry("ArrayLike"), typeEntry("Partial"), typeEntry("Required"), @@ -1292,6 +1283,7 @@ namespace FourSlashInterface { "let", "package", "yield", + "abstract", "as", "asserts", "any", @@ -1495,6 +1487,7 @@ namespace FourSlashInterface { "let", "package", "yield", + "abstract", "as", "asserts", "any", diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index e4730a2e9fdda..450ed9f6174f6 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -271,7 +271,7 @@ namespace Harness { } export function getDefaultLibFileName(options: ts.CompilerOptions): string { - switch (options.target) { + switch (ts.getEmitScriptTarget(options)) { case ts.ScriptTarget.ESNext: case ts.ScriptTarget.ES2017: return "lib.es2017.d.ts"; @@ -391,7 +391,7 @@ namespace Harness { symlinks?: vfs.FileSet ): compiler.CompilationResult { const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false }; - options.target = options.target || ts.ScriptTarget.ES3; + options.target = ts.getEmitScriptTarget(options); options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed; options.noErrorTruncation = true; options.skipDefaultLibCheck = typeof options.skipDefaultLibCheck === "undefined" ? true : options.skipDefaultLibCheck; @@ -505,7 +505,7 @@ namespace Harness { sourceFileName = outFile; } - const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.Extension.Dts; + const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.getDeclarationEmitExtensionForPath(sourceFileName); return result.dts.get(dTsFileName); } @@ -897,7 +897,7 @@ namespace Harness { jsCode += "\r\n"; } if (!result.diagnostics.length && !ts.endsWith(file.file, ts.Extension.Json)) { - const fileParseResult = ts.createSourceFile(file.file, file.text, options.target || ts.ScriptTarget.ES3, /*parentNodes*/ false, ts.endsWith(file.file, "x") ? ts.ScriptKind.JSX : ts.ScriptKind.JS); + const fileParseResult = ts.createSourceFile(file.file, file.text, ts.getEmitScriptTarget(options), /*parentNodes*/ false, ts.endsWith(file.file, "x") ? ts.ScriptKind.JSX : ts.ScriptKind.JS); if (ts.length(fileParseResult.parseDiagnostics)) { jsCode += getErrorBaseline([file.asTestFile()], fileParseResult.parseDiagnostics); return; diff --git a/src/harness/vpathUtil.ts b/src/harness/vpathUtil.ts index 31419e976fffb..44ef5b0f6af3f 100644 --- a/src/harness/vpathUtil.ts +++ b/src/harness/vpathUtil.ts @@ -108,7 +108,7 @@ namespace vpath { } export function isDeclaration(path: string) { - return extname(path, ".d.ts", /*ignoreCase*/ false).length > 0; + return ts.fileExtensionIsOneOf(path, [ts.Extension.Dmts, ts.Extension.Dcts, ts.Extension.Dts]); } export function isSourceMap(path: string) { diff --git a/src/lib/README.md b/src/lib/README.md index 1b51e2cfc64ab..15b81789d52a1 100644 --- a/src/lib/README.md +++ b/src/lib/README.md @@ -1,8 +1,26 @@ # Read this! -The files within this directory are used to generate `lib.d.ts` and `lib.es6.d.ts`. +The files within this directory are copied and deployed with TypeScript as the set of APIs available as a part of the JavaScript language. + +There are three main domains of APIs in `src/lib`: + + - **ECMAScript language features** - e.g. JavaScript APIs like functions on Array etc which are documented in [ECMA-262](https://tc39.es/ecma262/) + - **DOM APIs** - e.g. APIs which are available in web browsers + - **Intl APIs** - e.g. APIs scoped to `Intl` which are documented in [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/) + +## How do we figure out when to add something? + +TypeScript has a rule-of-thumb to only add something when it has got far enough through the standards process that it is more or less confirmed. For JavaScript APIs and language features, that means the proposal is at stage 3 or later. + +You can find the source of truth for modern language features and Intl APIs in these completed proposal lists: + + - [JavaScript](https://github.com/tc39/proposals/blob/master/finished-proposals.md) + - [Intl](https://github.com/tc39/proposals/blob/master/ecma402/finished-proposals.md) + +For the DOM APIs, which are a bit more free-form, we have asked that APIs are available un-prefixed/flagged in at least 2 browser _engines_ (i.e. not just 2 chromium browsers.) ## Generated files -Any files ending in `.generated.d.ts` aren't meant to be edited by hand. -If you need to make changes to such files, make a change to the input files for [**our library generator**](https://github.com/Microsoft/TSJS-lib-generator). +The DOM files ending in `.generated.d.ts` aren't meant to be edited by hand. + +If you need to make changes to such files, make a change to the input files for [**our library generator**](https://github.com/microsoft/TypeScript-DOM-lib-generator). diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index f8fd23d0fba6a..753d799299dc9 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -777,6 +777,7 @@ interface MediaStreamAudioSourceOptions { interface MediaStreamConstraints { audio?: boolean | MediaTrackConstraints; peerIdentity?: string; + preferCurrentTab?: boolean; video?: boolean | MediaTrackConstraints; } @@ -878,33 +879,19 @@ interface MultiCacheQueryOptions extends CacheQueryOptions { } interface MutationObserverInit { - /** - * Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. - */ + /** Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. */ attributeFilter?: string[]; - /** - * Set to true if attributes is true or omitted and target's attribute value before the mutation needs to be recorded. - */ + /** Set to true if attributes is true or omitted and target's attribute value before the mutation needs to be recorded. */ attributeOldValue?: boolean; - /** - * Set to true if mutations to target's attributes are to be observed. Can be omitted if attributeOldValue or attributeFilter is specified. - */ + /** Set to true if mutations to target's attributes are to be observed. Can be omitted if attributeOldValue or attributeFilter is specified. */ attributes?: boolean; - /** - * Set to true if mutations to target's data are to be observed. Can be omitted if characterDataOldValue is specified. - */ + /** Set to true if mutations to target's data are to be observed. Can be omitted if characterDataOldValue is specified. */ characterData?: boolean; - /** - * Set to true if characterData is set to true or omitted and target's data before the mutation needs to be recorded. - */ + /** Set to true if characterData is set to true or omitted and target's data before the mutation needs to be recorded. */ characterDataOldValue?: boolean; - /** - * Set to true if mutations to target's children are to be observed. - */ + /** Set to true if mutations to target's children are to be observed. */ childList?: boolean; - /** - * Set to true if mutations to not just target, but also target's descendants are to be observed. - */ + /** Set to true if mutations to not just target, but also target's descendants are to be observed. */ subtree?: boolean; } @@ -1094,10 +1081,6 @@ interface PositionOptions { timeout?: number; } -interface PostMessageOptions { - transfer?: any[]; -} - interface ProgressEventInit extends EventInit { lengthComputable?: boolean; loaded?: number; @@ -1455,57 +1438,31 @@ interface RegistrationOptions { } interface RequestInit { - /** - * A BodyInit object or null to set request's body. - */ + /** A BodyInit object or null to set request's body. */ body?: BodyInit | null; - /** - * A string indicating how the request will interact with the browser's cache to set request's cache. - */ + /** A string indicating how the request will interact with the browser's cache to set request's cache. */ cache?: RequestCache; - /** - * A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials. - */ + /** A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials. */ credentials?: RequestCredentials; - /** - * A Headers object, an object literal, or an array of two-item arrays to set request's headers. - */ + /** A Headers object, an object literal, or an array of two-item arrays to set request's headers. */ headers?: HeadersInit; - /** - * A cryptographic hash of the resource to be fetched by request. Sets request's integrity. - */ + /** A cryptographic hash of the resource to be fetched by request. Sets request's integrity. */ integrity?: string; - /** - * A boolean to set request's keepalive. - */ + /** A boolean to set request's keepalive. */ keepalive?: boolean; - /** - * A string to set request's method. - */ + /** A string to set request's method. */ method?: string; - /** - * A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode. - */ + /** A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode. */ mode?: RequestMode; - /** - * A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect. - */ + /** A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect. */ redirect?: RequestRedirect; - /** - * A string whose value is a same-origin URL, "about:client", or the empty string, to set request's referrer. - */ + /** A string whose value is a same-origin URL, "about:client", or the empty string, to set request's referrer. */ referrer?: string; - /** - * A referrer policy to set request's referrerPolicy. - */ + /** A referrer policy to set request's referrerPolicy. */ referrerPolicy?: ReferrerPolicy; - /** - * An AbortSignal to set request's signal. - */ + /** An AbortSignal to set request's signal. */ signal?: AbortSignal | null; - /** - * Can only be null. Used to disassociate request from any Window. - */ + /** Can only be null. Used to disassociate request from any Window. */ window?: any; } @@ -1664,6 +1621,10 @@ interface StreamPipeOptions { signal?: AbortSignal; } +interface StructuredSerializeOptions { + transfer?: any[]; +} + interface SubmitEventInit extends EventInit { submitter?: HTMLElement | null; } @@ -1791,7 +1752,7 @@ interface WheelEventInit extends MouseEventInit { deltaZ?: number; } -interface WindowPostMessageOptions extends PostMessageOptions { +interface WindowPostMessageOptions extends StructuredSerializeOptions { targetOrigin?: string; } @@ -1877,13 +1838,9 @@ interface ARIAMixin { /** A controller object that allows you to abort one or more DOM requests as and when desired. */ interface AbortController { - /** - * Returns the AbortSignal object associated with this object. - */ + /** Returns the AbortSignal object associated with this object. */ readonly signal: AbortSignal; - /** - * Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted. - */ + /** Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted. */ abort(): void; } @@ -1898,9 +1855,7 @@ interface AbortSignalEventMap { /** A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */ interface AbortSignal extends EventTarget { - /** - * Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise. - */ + /** Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise. */ readonly aborted: boolean; onabort: ((this: AbortSignal, ev: Event) => any) | null; addEventListener(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; @@ -1912,28 +1867,19 @@ interface AbortSignal extends EventTarget { declare var AbortSignal: { prototype: AbortSignal; new(): AbortSignal; + // abort(): AbortSignal; }; interface AbstractRange { - /** - * Returns true if range is collapsed, and false otherwise. - */ + /** Returns true if range is collapsed, and false otherwise. */ readonly collapsed: boolean; - /** - * Returns range's end node. - */ + /** Returns range's end node. */ readonly endContainer: Node; - /** - * Returns range's end offset. - */ + /** Returns range's end offset. */ readonly endOffset: number; - /** - * Returns range's start node. - */ + /** Returns range's start node. */ readonly startContainer: Node; - /** - * Returns range's start offset. - */ + /** Returns range's start offset. */ readonly startOffset: number; } @@ -2436,19 +2382,13 @@ interface BroadcastChannelEventMap { } interface BroadcastChannel extends EventTarget { - /** - * Returns the channel name (as passed to the constructor). - */ + /** Returns the channel name (as passed to the constructor). */ readonly name: string; onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null; onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null; - /** - * Closes the BroadcastChannel object, opening it up to garbage collection. - */ + /** Closes the BroadcastChannel object, opening it up to garbage collection. */ close(): void; - /** - * Sends the given message to other BroadcastChannel objects set up for this channel. Messages can be structured objects, e.g. nested objects and arrays. - */ + /** Sends the given message to other BroadcastChannel objects set up for this channel. Messages can be structured objects, e.g. nested objects and arrays. */ postMessage(message: any): void; addEventListener(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; @@ -3358,9 +3298,7 @@ interface CanvasPathDrawingStyles { /** An opaque object describing a pattern, based on an image, a canvas, or a video, created by the CanvasRenderingContext2D.createPattern() method. */ interface CanvasPattern { - /** - * Sets the transformation matrix that will be used when rendering the pattern during a fill or stroke painting operation. - */ + /** Sets the transformation matrix that will be used when rendering the pattern during a fill or stroke painting operation. */ setTransform(transform?: DOMMatrix2DInit): void; } @@ -3475,9 +3413,7 @@ interface ChildNode extends Node { * Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated. */ before(...nodes: (Node | string)[]): void; - /** - * Removes node. - */ + /** Removes node. */ remove(): void; /** * Replaces node with nodes, while replacing strings in nodes with equivalent Text nodes. @@ -3520,22 +3456,16 @@ interface ClipboardItem { declare var ClipboardItem: { prototype: ClipboardItem; - new(items: Record, options?: ClipboardItemOptions): ClipboardItem; + new(items: Record>, options?: ClipboardItemOptions): ClipboardItem; }; /** A CloseEvent is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the WebSocket object's onclose attribute. */ interface CloseEvent extends Event { - /** - * Returns the WebSocket connection close code provided by the server. - */ + /** Returns the WebSocket connection close code provided by the server. */ readonly code: number; - /** - * Returns the WebSocket connection close reason provided by the server. - */ + /** Returns the WebSocket connection close reason provided by the server. */ readonly reason: string; - /** - * Returns true if the connection closed cleanly; false otherwise. - */ + /** Returns true if the connection closed cleanly; false otherwise. */ readonly wasClean: boolean; } @@ -3659,9 +3589,7 @@ declare var CustomElementRegistry: { }; interface CustomEvent extends Event { - /** - * Returns any custom data event was created with. Typically used for synthetic events. - */ + /** Returns any custom data event was created with. Typically used for synthetic events. */ readonly detail: T; /** @deprecated */ initCustomEvent(type: string, bubbles?: boolean, cancelable?: boolean, detail?: T): void; @@ -3673,7 +3601,7 @@ declare var CustomEvent: { }; /** An abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API. */ -interface DOMException { +interface DOMException extends Error { readonly code: number; readonly message: string; readonly name: string; @@ -3967,17 +3895,11 @@ declare var DOMRectReadOnly: { /** A type returned by some APIs which contains a list of DOMString (strings). */ interface DOMStringList { - /** - * Returns the number of strings in strings. - */ + /** Returns the number of strings in strings. */ readonly length: number; - /** - * Returns true if strings contains string, and false otherwise. - */ + /** Returns true if strings contains string, and false otherwise. */ contains(string: string): boolean; - /** - * Returns the string with index index from strings. - */ + /** Returns the string with index index from strings. */ item(index: number): string | null; [index: number]: string; } @@ -3999,9 +3921,7 @@ declare var DOMStringMap: { /** A set of space-separated tokens. Such a set is returned by Element.classList, HTMLLinkElement.relList, HTMLAnchorElement.relList, HTMLAreaElement.relList, HTMLIframeElement.sandbox, or HTMLOutputElement.htmlFor. It is indexed beginning with 0 as with JavaScript Array objects. DOMTokenList is always case-sensitive. */ interface DOMTokenList { - /** - * Returns the number of tokens. - */ + /** Returns the number of tokens. */ readonly length: number; /** * Returns the associated set as string. @@ -4018,13 +3938,9 @@ interface DOMTokenList { * Throws an "InvalidCharacterError" DOMException if one of the arguments contains any ASCII whitespace. */ add(...tokens: string[]): void; - /** - * Returns true if token is present, and false otherwise. - */ + /** Returns true if token is present, and false otherwise. */ contains(token: string): boolean; - /** - * Returns the token with index index. - */ + /** Returns the token with index index. */ item(index: number): string | null; /** * Removes arguments passed, if they are present. @@ -4087,33 +4003,19 @@ interface DataTransfer { * The possible values are "none", "copy", "copyLink", "copyMove", "link", "linkMove", "move", "all", and "uninitialized", */ effectAllowed: "none" | "copy" | "copyLink" | "copyMove" | "link" | "linkMove" | "move" | "all" | "uninitialized"; - /** - * Returns a FileList of the files being dragged, if any. - */ + /** Returns a FileList of the files being dragged, if any. */ readonly files: FileList; - /** - * Returns a DataTransferItemList object, with the drag data. - */ + /** Returns a DataTransferItemList object, with the drag data. */ readonly items: DataTransferItemList; - /** - * Returns a frozen array listing the formats that were set in the dragstart event. In addition, if any files are being dragged, then one of the types will be the string "Files". - */ + /** Returns a frozen array listing the formats that were set in the dragstart event. In addition, if any files are being dragged, then one of the types will be the string "Files". */ readonly types: ReadonlyArray; - /** - * Removes the data of the specified formats. Removes all data if the argument is omitted. - */ + /** Removes the data of the specified formats. Removes all data if the argument is omitted. */ clearData(format?: string): void; - /** - * Returns the specified data. If there is no such data, returns the empty string. - */ + /** Returns the specified data. If there is no such data, returns the empty string. */ getData(format: string): string; - /** - * Adds the specified data. - */ + /** Adds the specified data. */ setData(format: string, data: string): void; - /** - * Uses the given element to update the drag feedback, replacing any previously specified feedback. - */ + /** Uses the given element to update the drag feedback, replacing any previously specified feedback. */ setDragImage(image: Element, x: number, y: number): void; } @@ -4124,21 +4026,13 @@ declare var DataTransfer: { /** One drag data item. During a drag operation, each drag event has a dataTransfer property which contains a list of drag data items. Each item in the list is a DataTransferItem object. */ interface DataTransferItem { - /** - * Returns the drag data item kind, one of: "string", "file". - */ + /** Returns the drag data item kind, one of: "string", "file". */ readonly kind: string; - /** - * Returns the drag data item type string. - */ + /** Returns the drag data item type string. */ readonly type: string; - /** - * Returns a File object, if the drag data item kind is File. - */ + /** Returns a File object, if the drag data item kind is File. */ getAsFile(): File | null; - /** - * Invokes the callback with the string data as the argument, if the drag data item kind is text. - */ + /** Invokes the callback with the string data as the argument, if the drag data item kind is text. */ getAsString(callback: FunctionStringCallback | null): void; webkitGetAsEntry(): FileSystemEntry | null; } @@ -4150,22 +4044,14 @@ declare var DataTransferItem: { /** A list of DataTransferItem objects representing items being dragged. During a drag operation, each DragEvent has a dataTransfer property and that property is a DataTransferItemList. */ interface DataTransferItemList { - /** - * Returns the number of items in the drag data store. - */ + /** Returns the number of items in the drag data store. */ readonly length: number; - /** - * Adds a new entry for the given data to the drag data store. If the data is plain text then a type string has to be provided also. - */ + /** Adds a new entry for the given data to the drag data store. If the data is plain text then a type string has to be provided also. */ add(data: string, type: string): DataTransferItem | null; add(data: File): DataTransferItem | null; - /** - * Removes all the entries in the drag data store. - */ + /** Removes all the entries in the drag data store. */ clear(): void; - /** - * Removes the indexth entry in the drag data store. - */ + /** Removes the indexth entry in the drag data store. */ remove(index: number): void; [index: number]: DataTransferItem; } @@ -4234,9 +4120,7 @@ interface DocumentEventMap extends DocumentAndElementEventHandlersEventMap, Glob /** Any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree. */ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShadowRoot, FontFaceSource, GlobalEventHandlers, NonElementParentNode, ParentNode, XPathEvaluatorBase { - /** - * Sets or gets the URL for the current document. - */ + /** Sets or gets the URL for the current document. */ readonly URL: string; /** * Sets or gets the color of all active links in the document. @@ -4263,26 +4147,18 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad * @deprecated */ bgColor: string; - /** - * Specifies the beginning and end of the document body. - */ + /** Specifies the beginning and end of the document body. */ body: HTMLElement; - /** - * Returns document's encoding. - */ + /** Returns document's encoding. */ readonly characterSet: string; /** * Gets or sets the character set used to encode the object. * @deprecated This is a legacy alias of `characterSet`. */ readonly charset: string; - /** - * Gets a value that indicates whether standards-compliant mode is switched on for the object. - */ + /** Gets a value that indicates whether standards-compliant mode is switched on for the object. */ readonly compatMode: string; - /** - * Returns document's content type. - */ + /** Returns document's content type. */ readonly contentType: string; /** * Returns the HTTP cookies that apply to the Document. If there are no cookies or cookies can't be applied to this resource, the empty string will be returned. @@ -4298,87 +4174,55 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad * Returns null if the Document is not currently executing a script or SVG script element (e.g., because the running script is an event handler, or a timeout), or if the currently executing script or SVG script element represents a module script. */ readonly currentScript: HTMLOrSVGScriptElement | null; - /** - * Returns the Window object of the active document. - */ + /** Returns the Window object of the active document. */ readonly defaultView: (WindowProxy & typeof globalThis) | null; - /** - * Sets or gets a value that indicates whether the document can be edited. - */ + /** Sets or gets a value that indicates whether the document can be edited. */ designMode: string; - /** - * Sets or retrieves a value that indicates the reading order of the object. - */ + /** Sets or retrieves a value that indicates the reading order of the object. */ dir: string; - /** - * Gets an object representing the document type declaration associated with the current document. - */ + /** Gets an object representing the document type declaration associated with the current document. */ readonly doctype: DocumentType | null; - /** - * Gets a reference to the root node of the document. - */ + /** Gets a reference to the root node of the document. */ readonly documentElement: HTMLElement; - /** - * Returns document's URL. - */ + /** Returns document's URL. */ readonly documentURI: string; - /** - * Sets or gets the security domain of the document. - */ + /** Sets or gets the security domain of the document. */ domain: string; - /** - * Retrieves a collection of all embed objects in the document. - */ + /** Retrieves a collection of all embed objects in the document. */ readonly embeds: HTMLCollectionOf; /** * Sets or gets the foreground (text) color of the document. * @deprecated */ fgColor: string; - /** - * Retrieves a collection, in source order, of all form objects in the document. - */ + /** Retrieves a collection, in source order, of all form objects in the document. */ readonly forms: HTMLCollectionOf; /** @deprecated */ readonly fullscreen: boolean; - /** - * Returns true if document has the ability to display elements fullscreen and fullscreen is supported, or false otherwise. - */ + /** Returns true if document has the ability to display elements fullscreen and fullscreen is supported, or false otherwise. */ readonly fullscreenEnabled: boolean; - /** - * Returns the head element. - */ + /** Returns the head element. */ readonly head: HTMLHeadElement; readonly hidden: boolean; - /** - * Retrieves a collection, in source order, of img objects in the document. - */ + /** Retrieves a collection, in source order, of img objects in the document. */ readonly images: HTMLCollectionOf; - /** - * Gets the implementation object of the current document. - */ + /** Gets the implementation object of the current document. */ readonly implementation: DOMImplementation; /** * Returns the character encoding used to create the webpage that is loaded into the document object. * @deprecated This is a legacy alias of `characterSet`. */ readonly inputEncoding: string; - /** - * Gets the date that the page was last modified, if the page supplies one. - */ + /** Gets the date that the page was last modified, if the page supplies one. */ readonly lastModified: string; /** * Sets or gets the color of the document links. * @deprecated */ linkColor: string; - /** - * Retrieves a collection of all a objects that specify the href property and all area objects in the document. - */ + /** Retrieves a collection of all a objects that specify the href property and all area objects in the document. */ readonly links: HTMLCollectionOf; - /** - * Contains information about the current URL. - */ + /** Contains information about the current URL. */ get location(): Location; set location(href: string | Location); onfullscreenchange: ((this: Document, ev: Event) => any) | null; @@ -4393,29 +4237,19 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad onvisibilitychange: ((this: Document, ev: Event) => any) | null; readonly ownerDocument: null; readonly pictureInPictureEnabled: boolean; - /** - * Return an HTMLCollection of the embed elements in the Document. - */ + /** Return an HTMLCollection of the embed elements in the Document. */ readonly plugins: HTMLCollectionOf; - /** - * Retrieves a value that indicates the current state of the object. - */ + /** Retrieves a value that indicates the current state of the object. */ readonly readyState: DocumentReadyState; - /** - * Gets the URL of the location that referred the user to the current page. - */ + /** Gets the URL of the location that referred the user to the current page. */ readonly referrer: string; /** @deprecated */ readonly rootElement: SVGSVGElement | null; - /** - * Retrieves a collection of all script objects in the document. - */ + /** Retrieves a collection of all script objects in the document. */ readonly scripts: HTMLCollectionOf; readonly scrollingElement: Element | null; readonly timeline: DocumentTimeline; - /** - * Contains the title of the document. - */ + /** Contains the title of the document. */ title: string; readonly visibilityState: VisibilityState; /** @@ -4435,9 +4269,7 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad caretRangeFromPoint(x: number, y: number): Range | null; /** @deprecated */ clear(): void; - /** - * Closes an output stream and forces the sent data to display. - */ + /** Closes an output stream and forces the sent data to display. */ close(): void; /** * Creates an attribute object with a specified name. @@ -4445,18 +4277,14 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad */ createAttribute(localName: string): Attr; createAttributeNS(namespace: string | null, qualifiedName: string): Attr; - /** - * Returns a CDATASection node whose data is data. - */ + /** Returns a CDATASection node whose data is data. */ createCDATASection(data: string): CDATASection; /** * Creates a comment object with the specified data. * @param data Sets the comment object's data. */ createComment(data: string): Comment; - /** - * Creates a new document. - */ + /** Creates a new document. */ createDocumentFragment(): DocumentFragment; /** * Creates an instance of the element for the specified tag. @@ -4550,13 +4378,9 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad * @param filter A custom NodeFilter function to use. For more information, see filter. Use null for no filter. */ createNodeIterator(root: Node, whatToShow?: number, filter?: NodeFilter | null): NodeIterator; - /** - * Returns a ProcessingInstruction node whose target is target and data is data. If target does not match the Name production an "InvalidCharacterError" DOMException will be thrown. If data contains "?>" an "InvalidCharacterError" DOMException will be thrown. - */ + /** Returns a ProcessingInstruction node whose target is target and data is data. If target does not match the Name production an "InvalidCharacterError" DOMException will be thrown. If data contains "?>" an "InvalidCharacterError" DOMException will be thrown. */ createProcessingInstruction(target: string, data: string): ProcessingInstruction; - /** - * Returns an empty range object that has both of its boundary points positioned at the beginning of the document. - */ + /** Returns an empty range object that has both of its boundary points positioned at the beginning of the document. */ createRange(): Range; /** * Creates a text string from the specified value. @@ -4585,9 +4409,7 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad * @deprecated */ execCommand(commandId: string, showUI?: boolean, value?: string): boolean; - /** - * Stops document's fullscreen element from being displayed fullscreen and resolves promise when done. - */ + /** Stops document's fullscreen element from being displayed fullscreen and resolves promise when done. */ exitFullscreen(): Promise; exitPictureInPicture(): Promise; exitPointerLock(): void; @@ -4596,9 +4418,7 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad * @param elementId String that specifies the ID value. */ getElementById(elementId: string): HTMLElement | null; - /** - * Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes. - */ + /** Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes. */ getElementsByClassName(classNames: string): HTMLCollectionOf; /** * Gets a collection of objects based on the value of the NAME or ID attribute. @@ -4624,13 +4444,9 @@ interface Document extends Node, DocumentAndElementEventHandlers, DocumentOrShad getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf; getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf; getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf; - /** - * Returns an object representing the current selection of the document that is loaded into the object displaying a webpage. - */ + /** Returns an object representing the current selection of the document that is loaded into the object displaying a webpage. */ getSelection(): Selection | null; - /** - * Gets a value indicating whether the object currently has focus. - */ + /** Gets a value indicating whether the object currently has focus. */ hasFocus(): boolean; hasStorageAccess(): Promise; /** @@ -4736,15 +4552,11 @@ interface DocumentOrShadowRoot { * Similarly, when the focused element is in a different node tree than documentOrShadowRoot, the element returned will be the host that's located in the same node tree as documentOrShadowRoot if documentOrShadowRoot is a shadow-including inclusive ancestor of the focused element, and null if not. */ readonly activeElement: Element | null; - /** - * Returns document's fullscreen element. - */ + /** Returns document's fullscreen element. */ readonly fullscreenElement: Element | null; readonly pictureInPictureElement: Element | null; readonly pointerLockElement: Element | null; - /** - * Retrieves a collection of styleSheet objects representing the style sheets that correspond to each instance of a link or style object in the document. - */ + /** Retrieves a collection of styleSheet objects representing the style sheets that correspond to each instance of a link or style object in the document. */ readonly styleSheets: StyleSheetList; getAnimations(): Animation[]; } @@ -4772,9 +4584,7 @@ declare var DocumentType: { /** A DOM event that represents a drag and drop interaction. The user initiates a drag by placing a pointer device (such as a mouse) on the touch surface and then dragging the pointer to a new location (such as another DOM element). Applications are free to interpret a drag and drop interaction in an application-specific way. */ interface DragEvent extends MouseEvent { - /** - * Returns the DataTransfer object for the event. - */ + /** Returns the DataTransfer object for the event. */ readonly dataTransfer: DataTransfer | null; } @@ -4851,84 +4661,54 @@ interface ElementEventMap { /** Element is the most general base class from which all objects in a Document inherit. It only has methods and properties common to all kinds of elements. More specific classes inherit from Element. */ interface Element extends Node, ARIAMixin, Animatable, ChildNode, InnerHTML, NonDocumentTypeChildNode, ParentNode, Slottable { readonly attributes: NamedNodeMap; - /** - * Allows for manipulation of element's class content attribute as a set of whitespace-separated tokens through a DOMTokenList object. - */ + /** Allows for manipulation of element's class content attribute as a set of whitespace-separated tokens through a DOMTokenList object. */ readonly classList: DOMTokenList; - /** - * Returns the value of element's class content attribute. Can be set to change it. - */ + /** Returns the value of element's class content attribute. Can be set to change it. */ className: string; readonly clientHeight: number; readonly clientLeft: number; readonly clientTop: number; readonly clientWidth: number; - /** - * Returns the value of element's id content attribute. Can be set to change it. - */ + /** Returns the value of element's id content attribute. Can be set to change it. */ id: string; - /** - * Returns the local name. - */ + /** Returns the local name. */ readonly localName: string; - /** - * Returns the namespace. - */ + /** Returns the namespace. */ readonly namespaceURI: string | null; onfullscreenchange: ((this: Element, ev: Event) => any) | null; onfullscreenerror: ((this: Element, ev: Event) => any) | null; outerHTML: string; readonly ownerDocument: Document; readonly part: DOMTokenList; - /** - * Returns the namespace prefix. - */ + /** Returns the namespace prefix. */ readonly prefix: string | null; readonly scrollHeight: number; scrollLeft: number; scrollTop: number; readonly scrollWidth: number; - /** - * Returns element's shadow root, if any, and if shadow root's mode is "open", and null otherwise. - */ + /** Returns element's shadow root, if any, and if shadow root's mode is "open", and null otherwise. */ readonly shadowRoot: ShadowRoot | null; - /** - * Returns the value of element's slot content attribute. Can be set to change it. - */ + /** Returns the value of element's slot content attribute. Can be set to change it. */ slot: string; - /** - * Returns the HTML-uppercased qualified name. - */ + /** Returns the HTML-uppercased qualified name. */ readonly tagName: string; - /** - * Creates a shadow root for element and returns it. - */ + /** Creates a shadow root for element and returns it. */ attachShadow(init: ShadowRootInit): ShadowRoot; - /** - * Returns the first (starting at element) inclusive ancestor that matches selectors, and null otherwise. - */ + /** Returns the first (starting at element) inclusive ancestor that matches selectors, and null otherwise. */ closest(selector: K): HTMLElementTagNameMap[K] | null; closest(selector: K): SVGElementTagNameMap[K] | null; closest(selectors: string): E | null; - /** - * Returns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise. - */ + /** Returns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise. */ getAttribute(qualifiedName: string): string | null; - /** - * Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise. - */ + /** Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise. */ getAttributeNS(namespace: string | null, localName: string): string | null; - /** - * Returns the qualified names of all element's attributes. Can contain duplicates. - */ + /** Returns the qualified names of all element's attributes. Can contain duplicates. */ getAttributeNames(): string[]; getAttributeNode(qualifiedName: string): Attr | null; getAttributeNodeNS(namespace: string | null, localName: string): Attr | null; getBoundingClientRect(): DOMRect; getClientRects(): DOMRectList; - /** - * Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes. - */ + /** Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes. */ getElementsByClassName(classNames: string): HTMLCollectionOf; getElementsByTagName(qualifiedName: K): HTMLCollectionOf; getElementsByTagName(qualifiedName: K): HTMLCollectionOf; @@ -4936,34 +4716,22 @@ interface Element extends Node, ARIAMixin, Animatable, ChildNode, InnerHTML, Non getElementsByTagNameNS(namespaceURI: "http://www.w3.org/1999/xhtml", localName: string): HTMLCollectionOf; getElementsByTagNameNS(namespaceURI: "http://www.w3.org/2000/svg", localName: string): HTMLCollectionOf; getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf; - /** - * Returns true if element has an attribute whose qualified name is qualifiedName, and false otherwise. - */ + /** Returns true if element has an attribute whose qualified name is qualifiedName, and false otherwise. */ hasAttribute(qualifiedName: string): boolean; - /** - * Returns true if element has an attribute whose namespace is namespace and local name is localName. - */ + /** Returns true if element has an attribute whose namespace is namespace and local name is localName. */ hasAttributeNS(namespace: string | null, localName: string): boolean; - /** - * Returns true if element has attributes, and false otherwise. - */ + /** Returns true if element has attributes, and false otherwise. */ hasAttributes(): boolean; hasPointerCapture(pointerId: number): boolean; insertAdjacentElement(where: InsertPosition, element: Element): Element | null; insertAdjacentHTML(position: InsertPosition, text: string): void; insertAdjacentText(where: InsertPosition, data: string): void; - /** - * Returns true if matching selectors against element's root yields element, and false otherwise. - */ + /** Returns true if matching selectors against element's root yields element, and false otherwise. */ matches(selectors: string): boolean; releasePointerCapture(pointerId: number): void; - /** - * Removes element's first attribute whose qualified name is qualifiedName. - */ + /** Removes element's first attribute whose qualified name is qualifiedName. */ removeAttribute(qualifiedName: string): void; - /** - * Removes element's attribute whose namespace is namespace and local name is localName. - */ + /** Removes element's attribute whose namespace is namespace and local name is localName. */ removeAttributeNS(namespace: string | null, localName: string): void; removeAttributeNode(attr: Attr): Attr; /** @@ -4980,13 +4748,9 @@ interface Element extends Node, ARIAMixin, Animatable, ChildNode, InnerHTML, Non scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void; scrollTo(options?: ScrollToOptions): void; scrollTo(x: number, y: number): void; - /** - * Sets the value of element's first attribute whose qualified name is qualifiedName to value. - */ + /** Sets the value of element's first attribute whose qualified name is qualifiedName to value. */ setAttribute(qualifiedName: string, value: string): void; - /** - * Sets the value of element's attribute whose namespace is namespace and local name is localName to value. - */ + /** Sets the value of element's attribute whose namespace is namespace and local name is localName to value. */ setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void; setAttributeNode(attr: Attr): Attr | null; setAttributeNodeNS(attr: Attr): Attr | null; @@ -5037,68 +4801,40 @@ declare var ErrorEvent: { /** An event which takes place in the DOM. */ interface Event { - /** - * Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise. - */ + /** Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise. */ readonly bubbles: boolean; cancelBubble: boolean; - /** - * Returns true or false depending on how event was initialized. Its return value does not always carry meaning, but true can indicate that part of the operation during which event was dispatched, can be canceled by invoking the preventDefault() method. - */ + /** Returns true or false depending on how event was initialized. Its return value does not always carry meaning, but true can indicate that part of the operation during which event was dispatched, can be canceled by invoking the preventDefault() method. */ readonly cancelable: boolean; - /** - * Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise. - */ + /** Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise. */ readonly composed: boolean; - /** - * Returns the object whose event listener's callback is currently being invoked. - */ + /** Returns the object whose event listener's callback is currently being invoked. */ readonly currentTarget: EventTarget | null; - /** - * Returns true if preventDefault() was invoked successfully to indicate cancelation, and false otherwise. - */ + /** Returns true if preventDefault() was invoked successfully to indicate cancelation, and false otherwise. */ readonly defaultPrevented: boolean; - /** - * Returns the event's phase, which is one of NONE, CAPTURING_PHASE, AT_TARGET, and BUBBLING_PHASE. - */ + /** Returns the event's phase, which is one of NONE, CAPTURING_PHASE, AT_TARGET, and BUBBLING_PHASE. */ readonly eventPhase: number; - /** - * Returns true if event was dispatched by the user agent, and false otherwise. - */ + /** Returns true if event was dispatched by the user agent, and false otherwise. */ readonly isTrusted: boolean; /** @deprecated */ returnValue: boolean; /** @deprecated */ readonly srcElement: EventTarget | null; - /** - * Returns the object to which event is dispatched (its target). - */ + /** Returns the object to which event is dispatched (its target). */ readonly target: EventTarget | null; - /** - * Returns the event's timestamp as the number of milliseconds measured relative to the time origin. - */ + /** Returns the event's timestamp as the number of milliseconds measured relative to the time origin. */ readonly timeStamp: DOMHighResTimeStamp; - /** - * Returns the type of event, e.g. "click", "hashchange", or "submit". - */ + /** Returns the type of event, e.g. "click", "hashchange", or "submit". */ readonly type: string; - /** - * Returns the invocation target objects of event's path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow root's mode is "closed" that are not reachable from event's currentTarget. - */ + /** Returns the invocation target objects of event's path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow root's mode is "closed" that are not reachable from event's currentTarget. */ composedPath(): EventTarget[]; /** @deprecated */ initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void; - /** - * If invoked when the cancelable attribute value is true, and while executing a listener for the event with passive set to false, signals to the operation that caused event to be dispatched that it needs to be canceled. - */ + /** If invoked when the cancelable attribute value is true, and while executing a listener for the event with passive set to false, signals to the operation that caused event to be dispatched that it needs to be canceled. */ preventDefault(): void; - /** - * Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects. - */ + /** Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects. */ stopImmediatePropagation(): void; - /** - * When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object. - */ + /** When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object. */ stopPropagation(): void; readonly AT_TARGET: number; readonly BUBBLING_PHASE: number; @@ -5133,21 +4869,13 @@ interface EventSource extends EventTarget { onerror: ((this: EventSource, ev: Event) => any) | null; onmessage: ((this: EventSource, ev: MessageEvent) => any) | null; onopen: ((this: EventSource, ev: Event) => any) | null; - /** - * Returns the state of this EventSource object's connection. It can have the values described below. - */ + /** Returns the state of this EventSource object's connection. It can have the values described below. */ readonly readyState: number; - /** - * Returns the URL providing the event stream. - */ + /** Returns the URL providing the event stream. */ readonly url: string; - /** - * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise. - */ + /** Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise. */ readonly withCredentials: boolean; - /** - * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED. - */ + /** Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED. */ close(): void; readonly CLOSED: number; readonly CONNECTING: number; @@ -5184,13 +4912,9 @@ interface EventTarget { * The event listener is appended to target's event listener list and is not appended if it has the same type, callback, and capture. */ addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; - /** - * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. - */ + /** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */ dispatchEvent(event: Event): boolean; - /** - * Removes the event listener in target's event listener list with the same type, callback, and options. - */ + /** Removes the event listener in target's event listener list with the same type, callback, and options. */ removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void; } @@ -5424,9 +5148,7 @@ declare var FormData: { }; interface FormDataEvent extends Event { - /** - * Returns a FormData object representing names and values of elements associated to the target form. Operations on the FormData object will affect form data to be submitted. - */ + /** Returns a FormData object representing names and values of elements associated to the target form. Operations on the FormData object will affect form data to be submitted. */ readonly formData: FormData; } @@ -5628,7 +5350,7 @@ interface GlobalEventHandlersEventMap { "selectionchange": Event; "selectstart": Event; "stalled": Event; - "submit": Event; + "submit": SubmitEvent; "suspend": Event; "timeupdate": Event; "toggle": Event; @@ -5883,7 +5605,7 @@ interface GlobalEventHandlers { * @param ev The event. */ onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null; - onsubmit: ((this: GlobalEventHandlers, ev: Event) => any) | null; + onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null; /** * Occurs if the load operation has been intentionally halted. * @param ev The event. @@ -5913,9 +5635,13 @@ interface GlobalEventHandlers { * @param ev The event. */ onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null; + /** @deprecated This is a legacy alias of `onanimationend`. */ onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null; + /** @deprecated This is a legacy alias of `onanimationiteration`. */ onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null; + /** @deprecated This is a legacy alias of `onanimationstart`. */ onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null; + /** @deprecated This is a legacy alias of `ontransitionend`. */ onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null; onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null; addEventListener(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; @@ -5925,13 +5651,9 @@ interface GlobalEventHandlers { } interface HTMLAllCollection { - /** - * Returns the number of elements in the collection. - */ + /** Returns the number of elements in the collection. */ readonly length: number; - /** - * Returns the item with index index from the collection (determined by tree order). - */ + /** Returns the item with index index from the collection (determined by tree order). */ item(nameOrIndex?: string): HTMLCollection | Element | null; /** * Returns the item with ID or name name from the collection. @@ -5962,9 +5684,7 @@ interface HTMLAnchorElement extends HTMLElement, HTMLHyperlinkElementUtils { */ coords: string; download: string; - /** - * Sets or retrieves the language code of the object. - */ + /** Sets or retrieves the language code of the object. */ hreflang: string; /** * Sets or retrieves the shape of the object. @@ -5973,9 +5693,7 @@ interface HTMLAnchorElement extends HTMLElement, HTMLHyperlinkElementUtils { name: string; ping: string; referrerPolicy: string; - /** - * Sets or retrieves the relationship between the object and the destination of the link. - */ + /** Sets or retrieves the relationship between the object and the destination of the link. */ rel: string; readonly relList: DOMTokenList; /** @@ -5988,13 +5706,9 @@ interface HTMLAnchorElement extends HTMLElement, HTMLHyperlinkElementUtils { * @deprecated */ shape: string; - /** - * Sets or retrieves the window or frame at which to target content. - */ + /** Sets or retrieves the window or frame at which to target content. */ target: string; - /** - * Retrieves or sets the text of the object as a string. - */ + /** Retrieves or sets the text of the object as a string. */ text: string; type: string; addEventListener(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; @@ -6010,13 +5724,9 @@ declare var HTMLAnchorElement: { /** Provides special properties and methods (beyond those of the regular object HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of elements. */ interface HTMLAreaElement extends HTMLElement, HTMLHyperlinkElementUtils { - /** - * Sets or retrieves a text alternative to the graphic. - */ + /** Sets or retrieves a text alternative to the graphic. */ alt: string; - /** - * Sets or retrieves the coordinates of the object. - */ + /** Sets or retrieves the coordinates of the object. */ coords: string; download: string; /** @@ -6028,13 +5738,9 @@ interface HTMLAreaElement extends HTMLElement, HTMLHyperlinkElementUtils { referrerPolicy: string; rel: string; readonly relList: DOMTokenList; - /** - * Sets or retrieves the shape of the object. - */ + /** Sets or retrieves the shape of the object. */ shape: string; - /** - * Sets or retrieves the window or frame at which to target content. - */ + /** Sets or retrieves the window or frame at which to target content. */ target: string; addEventListener(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; @@ -6080,13 +5786,9 @@ declare var HTMLBRElement: { /** Contains the base URI for a document. This object inherits all of the properties and methods as described in the HTMLElement interface. */ interface HTMLBaseElement extends HTMLElement { - /** - * Gets or sets the baseline URL on which relative links are based. - */ + /** Gets or sets the baseline URL on which relative links are based. */ href: string; - /** - * Sets or retrieves the window or frame at which to target content. - */ + /** Sets or retrieves the window or frame at which to target content. */ target: string; addEventListener(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; @@ -6133,58 +5835,32 @@ declare var HTMLBodyElement: { /** Provides properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating