diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 86acdb7c44b6d..f7031ad81f99c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1461,9 +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 requestedExternalEmitHelpers: ExternalEmitHelpers; - var externalHelpersModule: Symbol; var scanner: Scanner | undefined; var Symbol = objectAllocator.getSymbolConstructor(); @@ -49508,42 +49505,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { - if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { + if (compilerOptions.importHelpers) { const sourceFile = getSourceFileOfNode(location); if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) { const helpersModule = resolveHelpersModule(sourceFile, location); if (helpersModule !== unknownSymbol) { - const uncheckedHelpers = helpers & ~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); - } - 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); + 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; } - requestedExternalEmitHelpers |= helpers; } } } @@ -49606,10 +49604,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..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,6 +6140,7 @@ 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 + 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/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..c3c969e5188ff --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.errors.txt @@ -0,0 +1,62 @@ +/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'. + + +==== /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 {} + +==== /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 {} + ~~~ +!!! 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..ab72a88548539 --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.js @@ -0,0 +1,74 @@ +//// [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 {} + +//// [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 {} + + +//// [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* () { }); +} +//// [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 }); +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..d7bc24ba130cd --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.symbols @@ -0,0 +1,44 @@ +//// [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, --, --)) + +=== /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 {} +>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..2146d4ada811f --- /dev/null +++ b/tests/baselines/reference/tslibMultipleMissingHelper.types @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/tslibMultipleMissingHelper.ts] //// + +=== /package1/index.ts === +export {}; +async function foo(): Promise {} +>foo : () => Promise +> : ^^^^^^ + +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 {} +>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/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.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..aff45f53881d1 --- /dev/null +++ b/tests/baselines/reference/tslibNotFoundDifferentModules.types @@ -0,0 +1,39 @@ +//// [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/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..823fba2a7f10d --- /dev/null +++ b/tests/cases/compiler/tslibMultipleMissingHelper.ts @@ -0,0 +1,51 @@ +// @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/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", + "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 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