From 484c82158cba4a30874251ccdd6c4677f9039a5e Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 24 May 2024 13:12:46 -0700 Subject: [PATCH 1/5] add test showing bad tslib check behavior --- .../tslibNotFoundDifferentModules.js | 57 +++++++++++++++++++ .../tslibNotFoundDifferentModules.symbols | 36 ++++++++++++ .../tslibNotFoundDifferentModules.types | 37 ++++++++++++ .../compiler/tslibNotFoundDifferentModules.ts | 47 +++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 tests/baselines/reference/tslibNotFoundDifferentModules.js create mode 100644 tests/baselines/reference/tslibNotFoundDifferentModules.symbols create mode 100644 tests/baselines/reference/tslibNotFoundDifferentModules.types create mode 100644 tests/cases/compiler/tslibNotFoundDifferentModules.ts diff --git a/tests/baselines/reference/tslibNotFoundDifferentModules.js b/tests/baselines/reference/tslibNotFoundDifferentModules.js new file mode 100644 index 0000000000000..653b6029e906b --- /dev/null +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.js @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/tslibNotFoundDifferentModules.ts] //// + +//// [package.json] +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +//// [tslib.d.ts] +/** + * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`. + * + * @param thisArg The reference to use as the `this` value in the generator function + * @param _arguments The optional arguments array + * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object. + * @param generator The generator function + */ +export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; + +//// [tslib.js] +module.exports.__awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; + +//// [index.ts] +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +//// [index.ts] +export {}; +async function foo(): Promise {} + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +function bar() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} diff --git a/tests/baselines/reference/tslibNotFoundDifferentModules.symbols b/tests/baselines/reference/tslibNotFoundDifferentModules.symbols new file mode 100644 index 0000000000000..dcfba98e59314 --- /dev/null +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/tslibNotFoundDifferentModules.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +async function bar(): Promise {} +>bar : Symbol(bar, Decl(index.ts, 1, 38)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /package1/node_modules/tslib/tslib.d.ts === +/** + * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`. + * + * @param thisArg The reference to use as the `this` value in the generator function + * @param _arguments The optional arguments array + * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object. + * @param generator The generator function + */ +export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; +>__awaiter : Symbol(__awaiter, Decl(tslib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --)) +>_arguments : Symbol(_arguments, Decl(tslib.d.ts, --, --)) +>P : Symbol(P, Decl(tslib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>generator : Symbol(generator, Decl(tslib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + diff --git a/tests/baselines/reference/tslibNotFoundDifferentModules.types b/tests/baselines/reference/tslibNotFoundDifferentModules.types new file mode 100644 index 0000000000000..6888dadda8247 --- /dev/null +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.types @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/tslibNotFoundDifferentModules.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +async function bar(): Promise {} +>bar : () => Promise +> : ^^^^^^ + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +=== /package1/node_modules/tslib/tslib.d.ts === +/** + * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`. + * + * @param thisArg The reference to use as the `this` value in the generator function + * @param _arguments The optional arguments array + * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object. + * @param generator The generator function + */ +export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; +>__awaiter : (thisArg: any, _arguments: any, P: Function, generator: Function) => any +> : ^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>thisArg : any +>_arguments : any +>P : Function +> : ^^^^^^^^ +>generator : Function +> : ^^^^^^^^ + diff --git a/tests/cases/compiler/tslibNotFoundDifferentModules.ts b/tests/cases/compiler/tslibNotFoundDifferentModules.ts new file mode 100644 index 0000000000000..bca2b6bcd606f --- /dev/null +++ b/tests/cases/compiler/tslibNotFoundDifferentModules.ts @@ -0,0 +1,47 @@ +// @filename: /tsconfig.json +{ + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } +} + +// @filename: /package1/index.ts +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +// @filename: /package1/node_modules/tslib/package.json +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +// @filename: /package1/node_modules/tslib/tslib.d.ts +/** + * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`. + * + * @param thisArg The reference to use as the `this` value in the generator function + * @param _arguments The optional arguments array + * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object. + * @param generator The generator function + */ +export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; + +// @filename: /package1/node_modules/tslib/tslib.js +module.exports.__awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; + +// @filename: /package2/index.ts +export {}; +async function foo(): Promise {} \ No newline at end of file From e57ee584a4cd54b55921facfc73c80456cccdd0c Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 24 May 2024 14:22:53 -0700 Subject: [PATCH 2/5] check external emit helper for each file --- src/compiler/checker.ts | 21 ++++---- src/compiler/types.ts | 2 + .../esModuleInteropTslibHelpers.errors.txt | 10 +++- .../tslibNotFoundDifferentModules.errors.txt | 52 +++++++++++++++++++ .../tslibNotFoundDifferentModules.types | 2 + 5 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/tslibNotFoundDifferentModules.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 86acdb7c44b6d..6628cdcfd82f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1462,8 +1462,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var cancellationToken: CancellationToken | undefined; var requestedExternalEmitHelperNames = new Set(); - var requestedExternalEmitHelpers: ExternalEmitHelpers; - var externalHelpersModule: Symbol; var scanner: Scanner | undefined; var Symbol = objectAllocator.getSymbolConstructor(); @@ -49508,12 +49506,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { - if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { - const sourceFile = getSourceFileOfNode(location); - if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { + const sourceFile = getSourceFileOfNode(location); + if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { + const links = getNodeLinks(sourceFile); + links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers; + if ((links.requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { const helpersModule = resolveHelpersModule(sourceFile, location); if (helpersModule !== unknownSymbol) { - const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers; + const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers; for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { if (uncheckedHelpers & helper) { for (const name of getHelperNames(helper)) { @@ -49543,7 +49543,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - requestedExternalEmitHelpers |= helpers; + links.requestedExternalEmitHelpers |= helpers; } } } @@ -49606,10 +49606,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function resolveHelpersModule(file: SourceFile, errorNode: Node) { - if (!externalHelpersModule) { - externalHelpersModule = resolveExternalModule(getImportHelpersImportSpecifier(file), externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; + const links = getNodeLinks(file); + if (!links.externalHelpersModule) { + links.externalHelpersModule = resolveExternalModule(getImportHelpersImportSpecifier(file), externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; } - return externalHelpersModule; + return links.externalHelpersModule; } // GRAMMAR CHECKING diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b3c58c5c72719..baa0cf83a26cc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6139,6 +6139,8 @@ export interface NodeLinks { parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined". fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain. assertionExpressionType?: Type; // Cached type of the expression of a type assertion + requestedExternalEmitHelpers?: ExternalEmitHelpers; // External emit helpers already requested for this node. + externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module } /** @internal */ diff --git a/tests/baselines/reference/esModuleInteropTslibHelpers.errors.txt b/tests/baselines/reference/esModuleInteropTslibHelpers.errors.txt index d7dade1966e03..5fe5b5fd20ba1 100644 --- a/tests/baselines/reference/esModuleInteropTslibHelpers.errors.txt +++ b/tests/baselines/reference/esModuleInteropTslibHelpers.errors.txt @@ -1,4 +1,6 @@ file2.ts(1,1): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. +file3.ts(1,9): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. +file4.ts(1,14): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. ==== refs.d.ts (0 errors) ==== @@ -13,11 +15,15 @@ file2.ts(1,1): error TS2354: This syntax requires an imported helper but module !!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. path.resolve("", "../"); export class Foo2 { } -==== file3.ts (0 errors) ==== +==== file3.ts (1 errors) ==== import {default as resolve} from "path"; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. resolve("", "../"); export class Foo3 { } -==== file4.ts (0 errors) ==== +==== file4.ts (1 errors) ==== import {Bar, default as resolve} from "path"; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. resolve("", "../"); export { Bar } \ No newline at end of file diff --git a/tests/baselines/reference/tslibNotFoundDifferentModules.errors.txt b/tests/baselines/reference/tslibNotFoundDifferentModules.errors.txt new file mode 100644 index 0000000000000..d940afde05f81 --- /dev/null +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.errors.txt @@ -0,0 +1,52 @@ +/package2/index.ts(2,16): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } + } + +==== /package1/index.ts (0 errors) ==== + export {}; + async function foo(): Promise {} + async function bar(): Promise {} + +==== /package2/index.ts (1 errors) ==== + export {}; + async function foo(): Promise {} + ~~~ +!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. +==== /package1/node_modules/tslib/package.json (0 errors) ==== + { + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" + } + +==== /package1/node_modules/tslib/tslib.d.ts (0 errors) ==== + /** + * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`. + * + * @param thisArg The reference to use as the `this` value in the generator function + * @param _arguments The optional arguments array + * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object. + * @param generator The generator function + */ + export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; + +==== /package1/node_modules/tslib/tslib.js (0 errors) ==== + module.exports.__awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + \ No newline at end of file diff --git a/tests/baselines/reference/tslibNotFoundDifferentModules.types b/tests/baselines/reference/tslibNotFoundDifferentModules.types index 6888dadda8247..aff45f53881d1 100644 --- a/tests/baselines/reference/tslibNotFoundDifferentModules.types +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.types @@ -29,7 +29,9 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge >__awaiter : (thisArg: any, _arguments: any, P: Function, generator: Function) => any > : ^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ >thisArg : any +> : ^^^ >_arguments : any +> : ^^^ >P : Function > : ^^^^^^^^ >generator : Function From 2eb4081192d8ed7ff30eef7e4730409e8a04292c Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 28 May 2024 10:57:18 -0700 Subject: [PATCH 3/5] only check tslib helpers once per symbol --- src/compiler/checker.ts | 16 +++--- src/compiler/types.ts | 2 +- .../reference/tslibMissingHelper.errors.txt | 36 +++++++++++++ .../baselines/reference/tslibMissingHelper.js | 41 ++++++++++++++ .../reference/tslibMissingHelper.symbols | 22 ++++++++ .../reference/tslibMissingHelper.types | 23 ++++++++ .../tslibMultipleMissingHelper.errors.txt | 52 ++++++++++++++++++ .../reference/tslibMultipleMissingHelper.js | 54 +++++++++++++++++++ .../tslibMultipleMissingHelper.symbols | 26 +++++++++ .../tslibMultipleMissingHelper.types | 28 ++++++++++ tests/cases/compiler/tslibMissingHelper.ts | 31 +++++++++++ .../compiler/tslibMultipleMissingHelper.ts | 44 +++++++++++++++ 12 files changed, 364 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/tslibMissingHelper.errors.txt create mode 100644 tests/baselines/reference/tslibMissingHelper.js create mode 100644 tests/baselines/reference/tslibMissingHelper.symbols create mode 100644 tests/baselines/reference/tslibMissingHelper.types create mode 100644 tests/baselines/reference/tslibMultipleMissingHelper.errors.txt create mode 100644 tests/baselines/reference/tslibMultipleMissingHelper.js create mode 100644 tests/baselines/reference/tslibMultipleMissingHelper.symbols create mode 100644 tests/baselines/reference/tslibMultipleMissingHelper.types create mode 100644 tests/cases/compiler/tslibMissingHelper.ts create mode 100644 tests/cases/compiler/tslibMultipleMissingHelper.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6628cdcfd82f0..623420d7e0de9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1461,7 +1461,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // they no longer need the information (for example, if the user started editing again). var cancellationToken: CancellationToken | undefined; - var requestedExternalEmitHelperNames = new Set(); var scanner: Scanner | undefined; var Symbol = objectAllocator.getSymbolConstructor(); @@ -49507,19 +49506,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { const sourceFile = getSourceFileOfNode(location); - if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { - const links = getNodeLinks(sourceFile); - links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers; - if ((links.requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { - const helpersModule = resolveHelpersModule(sourceFile, location); - if (helpersModule !== unknownSymbol) { + if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { + const helpersModule = resolveHelpersModule(sourceFile, location); + if (helpersModule !== unknownSymbol) { + const links = getSymbolLinks(helpersModule); + links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers; + if ((links.requestedExternalEmitHelpers & helpers) !== helpers) { const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers; for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { if (uncheckedHelpers & helper) { for (const name of getHelperNames(helper)) { - if (requestedExternalEmitHelperNames.has(name)) continue; - requestedExternalEmitHelperNames.add(name); - const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), SymbolFlags.Value)); if (!symbol) { error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index baa0cf83a26cc..d5c6178332d04 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5953,6 +5953,7 @@ export interface SymbolLinks { tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label accessibleChainCache?: Map; filteredIndexSymbolCache?: Map //Symbol with applicable declarations + requestedExternalEmitHelpers?: ExternalEmitHelpers; // External emit helpers already checked for this symbol. } // dprint-ignore @@ -6139,7 +6140,6 @@ export interface NodeLinks { parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined". fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain. assertionExpressionType?: Type; // Cached type of the expression of a type assertion - requestedExternalEmitHelpers?: ExternalEmitHelpers; // External emit helpers already requested for this node. externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module } diff --git a/tests/baselines/reference/tslibMissingHelper.errors.txt b/tests/baselines/reference/tslibMissingHelper.errors.txt new file mode 100644 index 0000000000000..114311a80fa7f --- /dev/null +++ b/tests/baselines/reference/tslibMissingHelper.errors.txt @@ -0,0 +1,36 @@ +/package1/index.ts(2,16): error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } + } + +==== /package1/index.ts (1 errors) ==== + export {}; + async function foo(): Promise {} + ~~~ +!!! error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + async function bar(): Promise {} + +==== /package2/index.ts (0 errors) ==== + export {}; + async function foo(): Promise {} + +==== /node_modules/tslib/package.json (0 errors) ==== + { + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" + } + +==== /node_modules/tslib/tslib.d.ts (0 errors) ==== + export const notAHelper: any; + +==== /node_modules/tslib/tslib.js (0 errors) ==== + module.exports.notAHelper = 3; \ No newline at end of file diff --git a/tests/baselines/reference/tslibMissingHelper.js b/tests/baselines/reference/tslibMissingHelper.js new file mode 100644 index 0000000000000..d75b73508b398 --- /dev/null +++ b/tests/baselines/reference/tslibMissingHelper.js @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/tslibMissingHelper.ts] //// + +//// [package.json] +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +//// [tslib.d.ts] +export const notAHelper: any; + +//// [tslib.js] +module.exports.notAHelper = 3; +//// [index.ts] +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +//// [index.ts] +export {}; +async function foo(): Promise {} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +function bar() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} diff --git a/tests/baselines/reference/tslibMissingHelper.symbols b/tests/baselines/reference/tslibMissingHelper.symbols new file mode 100644 index 0000000000000..032ff48ad61e3 --- /dev/null +++ b/tests/baselines/reference/tslibMissingHelper.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/tslibMissingHelper.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +async function bar(): Promise {} +>bar : Symbol(bar, Decl(index.ts, 1, 38)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : Symbol(notAHelper, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/tslibMissingHelper.types b/tests/baselines/reference/tslibMissingHelper.types new file mode 100644 index 0000000000000..ddd96fe0bbfcb --- /dev/null +++ b/tests/baselines/reference/tslibMissingHelper.types @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/tslibMissingHelper.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +async function bar(): Promise {} +>bar : () => Promise +> : ^^^^^^ + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +=== /node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : any +> : ^^^ + diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt b/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt new file mode 100644 index 0000000000000..3da17c774d31b --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt @@ -0,0 +1,52 @@ +/package1/index.ts(2,16): error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. +/package2/index.ts(2,16): error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + + +==== /tsconfig.json (0 errors) ==== + { + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } + } + +==== /package1/index.ts (1 errors) ==== + export {}; + async function foo(): Promise {} + ~~~ +!!! error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + async function bar(): Promise {} + +==== /package2/index.ts (1 errors) ==== + export {}; + async function foo(): Promise {} + ~~~ +!!! error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + +==== /package1/node_modules/tslib/package.json (0 errors) ==== + { + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" + } + +==== /package1/node_modules/tslib/tslib.d.ts (0 errors) ==== + export const notAHelper: any; + +==== /package1/node_modules/tslib/tslib.js (0 errors) ==== + module.exports.notAHelper = 3; + +==== /package2/node_modules/tslib/package.json (0 errors) ==== + { + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" + } + +==== /package2/node_modules/tslib/tslib.d.ts (0 errors) ==== + export const notAHelper: any; + +==== /package2/node_modules/tslib/tslib.js (0 errors) ==== + module.exports.notAHelper = 3; \ No newline at end of file diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.js b/tests/baselines/reference/tslibMultipleMissingHelper.js new file mode 100644 index 0000000000000..ea1eb417a56e3 --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.js @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/tslibMultipleMissingHelper.ts] //// + +//// [package.json] +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +//// [tslib.d.ts] +export const notAHelper: any; + +//// [tslib.js] +module.exports.notAHelper = 3; + +//// [package.json] +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +//// [tslib.d.ts] +export const notAHelper: any; + +//// [tslib.js] +module.exports.notAHelper = 3; +//// [index.ts] +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +//// [index.ts] +export {}; +async function foo(): Promise {} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +function bar() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +function foo() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.symbols b/tests/baselines/reference/tslibMultipleMissingHelper.symbols new file mode 100644 index 0000000000000..bdec42febd472 --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.symbols @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/tslibMultipleMissingHelper.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +async function bar(): Promise {} +>bar : Symbol(bar, Decl(index.ts, 1, 38)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : Symbol(foo, Decl(index.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +=== /package1/node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : Symbol(notAHelper, Decl(tslib.d.ts, --, --)) + +=== /package2/node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : Symbol(notAHelper, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.types b/tests/baselines/reference/tslibMultipleMissingHelper.types new file mode 100644 index 0000000000000..b7b945ffe559f --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.types @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/tslibMultipleMissingHelper.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +async function bar(): Promise {} +>bar : () => Promise +> : ^^^^^^ + +=== /package2/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +=== /package1/node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : any +> : ^^^ + +=== /package2/node_modules/tslib/tslib.d.ts === +export const notAHelper: any; +>notAHelper : any +> : ^^^ + diff --git a/tests/cases/compiler/tslibMissingHelper.ts b/tests/cases/compiler/tslibMissingHelper.ts new file mode 100644 index 0000000000000..a9f721a8e1292 --- /dev/null +++ b/tests/cases/compiler/tslibMissingHelper.ts @@ -0,0 +1,31 @@ +// @filename: /tsconfig.json +{ + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } +} + +// @filename: /package1/index.ts +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +// @filename: /package2/index.ts +export {}; +async function foo(): Promise {} + +// @filename: /node_modules/tslib/package.json +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +// @filename: /node_modules/tslib/tslib.d.ts +export const notAHelper: any; + +// @filename: /node_modules/tslib/tslib.js +module.exports.notAHelper = 3; \ No newline at end of file diff --git a/tests/cases/compiler/tslibMultipleMissingHelper.ts b/tests/cases/compiler/tslibMultipleMissingHelper.ts new file mode 100644 index 0000000000000..6620330cd2e63 --- /dev/null +++ b/tests/cases/compiler/tslibMultipleMissingHelper.ts @@ -0,0 +1,44 @@ +// @filename: /tsconfig.json +{ + "compilerOptions": { + "strict": true, + "target": "ES2016", + "importHelpers": true, + "module": "commonjs", + } +} + +// @filename: /package1/index.ts +export {}; +async function foo(): Promise {} +async function bar(): Promise {} + +// @filename: /package1/node_modules/tslib/package.json +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +// @filename: /package1/node_modules/tslib/tslib.d.ts +export const notAHelper: any; + +// @filename: /package1/node_modules/tslib/tslib.js +module.exports.notAHelper = 3; + +// @filename: /package2/index.ts +export {}; +async function foo(): Promise {} + +// @filename: /package2/node_modules/tslib/package.json +{ + "name": "tslib", + "main": "tslib.js", + "typings": "tslib.d.ts" +} + +// @filename: /package2/node_modules/tslib/tslib.d.ts +export const notAHelper: any; + +// @filename: /package2/node_modules/tslib/tslib.js +module.exports.notAHelper = 3; \ No newline at end of file From c9d075c71580fa9f3b96995d8851ed30b9174820 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 28 May 2024 12:46:26 -0700 Subject: [PATCH 4/5] update multiple helper errors case --- .../tslibMultipleMissingHelper.errors.txt | 10 +++++++ .../reference/tslibMultipleMissingHelper.js | 20 +++++++++++++ .../tslibMultipleMissingHelper.symbols | 18 ++++++++++++ .../tslibMultipleMissingHelper.types | 29 +++++++++++++++++++ .../compiler/tslibMultipleMissingHelper.ts | 7 +++++ 5 files changed, 84 insertions(+) diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt b/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt index 3da17c774d31b..c3c969e5188ff 100644 --- a/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt +++ b/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt @@ -1,4 +1,5 @@ /package1/index.ts(2,16): error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. +/package1/other.ts(3,32): error TS2343: This syntax requires an imported helper named '__rest' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. /package2/index.ts(2,16): error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. @@ -19,6 +20,15 @@ !!! error TS2343: This syntax requires an imported helper named '__awaiter' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. async function bar(): Promise {} +==== /package1/other.ts (1 errors) ==== + export {}; + export async function noop(): Promise {} + export function spread({ a, ...rest }: { a: number, b: number}) { + ~~~~ +!!! error TS2343: This syntax requires an imported helper named '__rest' which does not exist in 'tslib'. Consider upgrading your version of 'tslib'. + return { c: "c", ...rest }; + } + ==== /package2/index.ts (1 errors) ==== export {}; async function foo(): Promise {} diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.js b/tests/baselines/reference/tslibMultipleMissingHelper.js index ea1eb417a56e3..ab72a88548539 100644 --- a/tests/baselines/reference/tslibMultipleMissingHelper.js +++ b/tests/baselines/reference/tslibMultipleMissingHelper.js @@ -30,6 +30,13 @@ export {}; async function foo(): Promise {} async function bar(): Promise {} +//// [other.ts] +export {}; +export async function noop(): Promise {} +export function spread({ a, ...rest }: { a: number, b: number}) { + return { c: "c", ...rest }; +} + //// [index.ts] export {}; async function foo(): Promise {} @@ -45,6 +52,19 @@ function foo() { function bar() { return tslib_1.__awaiter(this, void 0, void 0, function* () { }); } +//// [other.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.noop = noop; +exports.spread = spread; +const tslib_1 = require("tslib"); +function noop() { + return tslib_1.__awaiter(this, void 0, void 0, function* () { }); +} +function spread(_a) { + var { a } = _a, rest = tslib_1.__rest(_a, ["a"]); + return Object.assign({ c: "c" }, rest); +} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.symbols b/tests/baselines/reference/tslibMultipleMissingHelper.symbols index bdec42febd472..d7bc24ba130cd 100644 --- a/tests/baselines/reference/tslibMultipleMissingHelper.symbols +++ b/tests/baselines/reference/tslibMultipleMissingHelper.symbols @@ -10,6 +10,24 @@ async function bar(): Promise {} >bar : Symbol(bar, Decl(index.ts, 1, 38)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +=== /package1/other.ts === +export {}; +export async function noop(): Promise {} +>noop : Symbol(noop, Decl(other.ts, 0, 10)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +export function spread({ a, ...rest }: { a: number, b: number}) { +>spread : Symbol(spread, Decl(other.ts, 1, 46)) +>a : Symbol(a, Decl(other.ts, 2, 24)) +>rest : Symbol(rest, Decl(other.ts, 2, 27)) +>a : Symbol(a, Decl(other.ts, 2, 40)) +>b : Symbol(b, Decl(other.ts, 2, 51)) + + return { c: "c", ...rest }; +>c : Symbol(c, Decl(other.ts, 3, 12)) +>rest : Symbol(rest, Decl(other.ts, 2, 27)) +} + === /package2/index.ts === export {}; async function foo(): Promise {} diff --git a/tests/baselines/reference/tslibMultipleMissingHelper.types b/tests/baselines/reference/tslibMultipleMissingHelper.types index b7b945ffe559f..2146d4ada811f 100644 --- a/tests/baselines/reference/tslibMultipleMissingHelper.types +++ b/tests/baselines/reference/tslibMultipleMissingHelper.types @@ -10,6 +10,35 @@ async function bar(): Promise {} >bar : () => Promise > : ^^^^^^ +=== /package1/other.ts === +export {}; +export async function noop(): Promise {} +>noop : () => Promise +> : ^^^^^^ + +export function spread({ a, ...rest }: { a: number, b: number}) { +>spread : ({ a, ...rest }: { a: number; b: number; }) => { b: number; c: string; } +> : ^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ +>a : number +> : ^^^^^^ +>rest : { b: number; } +> : ^^^^^ ^^^ +>a : number +> : ^^^^^^ +>b : number +> : ^^^^^^ + + return { c: "c", ...rest }; +>{ c: "c", ...rest } : { b: number; c: string; } +> : ^^^^^ ^^^^^^^^^^^^^^ +>c : string +> : ^^^^^^ +>"c" : "c" +> : ^^^ +>rest : { b: number; } +> : ^^^^^ ^^^ +} + === /package2/index.ts === export {}; async function foo(): Promise {} diff --git a/tests/cases/compiler/tslibMultipleMissingHelper.ts b/tests/cases/compiler/tslibMultipleMissingHelper.ts index 6620330cd2e63..823fba2a7f10d 100644 --- a/tests/cases/compiler/tslibMultipleMissingHelper.ts +++ b/tests/cases/compiler/tslibMultipleMissingHelper.ts @@ -13,6 +13,13 @@ export {}; async function foo(): Promise {} async function bar(): Promise {} +// @filename: /package1/other.ts +export {}; +export async function noop(): Promise {} +export function spread({ a, ...rest }: { a: number, b: number}) { + return { c: "c", ...rest }; +} + // @filename: /package1/node_modules/tslib/package.json { "name": "tslib", From bcb28ffe1cc9dd98642da33b01c5f86153ed4a26 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 28 May 2024 14:16:31 -0700 Subject: [PATCH 5/5] CR: optimization --- src/compiler/checker.ts | 56 +++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 623420d7e0de9..f7031ad81f99c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -49505,41 +49505,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { - const sourceFile = getSourceFileOfNode(location); - if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { - const helpersModule = resolveHelpersModule(sourceFile, location); - if (helpersModule !== unknownSymbol) { - const links = getSymbolLinks(helpersModule); - links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers; - if ((links.requestedExternalEmitHelpers & helpers) !== helpers) { - const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers; - for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { - if (uncheckedHelpers & helper) { - for (const name of getHelperNames(helper)) { - const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), SymbolFlags.Value)); - if (!symbol) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name); - } - else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4); + if (compilerOptions.importHelpers) { + const sourceFile = getSourceFileOfNode(location); + if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { + const helpersModule = resolveHelpersModule(sourceFile, location); + if (helpersModule !== unknownSymbol) { + const links = getSymbolLinks(helpersModule); + links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers; + if ((links.requestedExternalEmitHelpers & helpers) !== helpers) { + const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers; + for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { + if (uncheckedHelpers & helper) { + for (const name of getHelperNames(helper)) { + const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), SymbolFlags.Value)); + if (!symbol) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name); } - } - else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5); + else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) { + if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4); + } } - } - else if (helper & ExternalEmitHelpers.SpreadArray) { - if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) { - error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3); + else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) { + if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5); + } + } + else if (helper & ExternalEmitHelpers.SpreadArray) { + if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3); + } } } } } } + links.requestedExternalEmitHelpers |= helpers; } - links.requestedExternalEmitHelpers |= helpers; } } }