@@ -38,6 +38,8 @@ namespace ts {
3838 // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
3939 // they no longer need the information (for example, if the user started editing again).
4040 let cancellationToken: CancellationToken;
41+ let requestedExternalEmitHelpers: ExternalEmitHelpers;
42+ let externalHelpersModule: Symbol;
4143
4244 const Symbol = objectAllocator.getSymbolConstructor();
4345 const Type = objectAllocator.getTypeConstructor();
@@ -11272,6 +11274,9 @@ namespace ts {
1127211274 member = prop;
1127311275 }
1127411276 else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
11277+ if (languageVersion < ScriptTarget.ESNext) {
11278+ checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
11279+ }
1127511280 if (propertiesArray.length > 0) {
1127611281 spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
1127711282 propertiesArray = [];
@@ -11459,6 +11464,9 @@ namespace ts {
1145911464 }
1146011465
1146111466 function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
11467+ if (compilerOptions.jsx === JsxEmit.React) {
11468+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Assign);
11469+ }
1146211470 const type = checkExpression(node.expression);
1146311471 const props = getPropertiesOfType(type);
1146411472 for (const prop of props) {
@@ -14223,6 +14231,9 @@ namespace ts {
1422314231 }
1422414232 }
1422514233 else if (property.kind === SyntaxKind.SpreadAssignment) {
14234+ if (languageVersion < ScriptTarget.ESNext) {
14235+ checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
14236+ }
1422614237 checkReferenceExpression(property.expression, Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access);
1422714238 }
1422814239 else {
@@ -15107,6 +15118,13 @@ namespace ts {
1510715118 checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
1510815119 }
1510915120
15121+ if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) {
15122+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
15123+ if (languageVersion < ScriptTarget.ES2015) {
15124+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
15125+ }
15126+ }
15127+
1511015128 checkTypeParameters(node.typeParameters);
1511115129
1511215130 forEach(node.parameters, checkParameter);
@@ -16242,7 +16260,15 @@ namespace ts {
1624216260 error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning);
1624316261 }
1624416262
16263+ const firstDecorator = node.decorators[0];
16264+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate);
16265+ if (node.kind === SyntaxKind.Parameter) {
16266+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param);
16267+ }
16268+
1624516269 if (compilerOptions.emitDecoratorMetadata) {
16270+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
16271+
1624616272 // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
1624716273 switch (node.kind) {
1624816274 case SyntaxKind.ClassDeclaration:
@@ -16629,7 +16655,7 @@ namespace ts {
1662916655 }
1663016656
1663116657 function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
16632- if (!needCollisionCheckForIdentifier(node, name, "Promise")) {
16658+ if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
1663316659 return;
1663416660 }
1663516661
@@ -16806,6 +16832,9 @@ namespace ts {
1680616832 }
1680716833
1680816834 if (node.kind === SyntaxKind.BindingElement) {
16835+ if (node.parent.kind === SyntaxKind.ObjectBindingPattern && languageVersion < ScriptTarget.ESNext) {
16836+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest);
16837+ }
1680916838 // check computed properties inside property names of binding elements
1681016839 if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
1681116840 checkComputedPropertyName(<ComputedPropertyName>node.propertyName);
@@ -17724,6 +17753,10 @@ namespace ts {
1772417753
1772517754 const baseTypeNode = getClassExtendsHeritageClauseElement(node);
1772617755 if (baseTypeNode) {
17756+ if (languageVersion < ScriptTarget.ES2015) {
17757+ checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends);
17758+ }
17759+
1772717760 const baseTypes = getBaseTypes(type);
1772817761 if (baseTypes.length && produceDiagnostics) {
1772917762 const baseType = baseTypes[0];
@@ -20164,8 +20197,6 @@ namespace ts {
2016420197
2016520198 // Initialize global symbol table
2016620199 let augmentations: LiteralExpression[][];
20167- let requestedExternalEmitHelpers: NodeFlags = 0;
20168- let firstFileRequestingExternalHelpers: SourceFile;
2016920200 for (const file of host.getSourceFiles()) {
2017020201 if (!isExternalOrCommonJsModule(file)) {
2017120202 mergeSymbolTable(globals, file.locals);
@@ -20185,15 +20216,6 @@ namespace ts {
2018520216 }
2018620217 }
2018720218 }
20188- if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) {
20189- const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags;
20190- if (fileRequestedExternalEmitHelpers) {
20191- requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers;
20192- if (firstFileRequestingExternalHelpers === undefined) {
20193- firstFileRequestingExternalHelpers = file;
20194- }
20195- }
20196- }
2019720219 }
2019820220
2019920221 if (augmentations) {
@@ -20259,57 +20281,51 @@ namespace ts {
2025920281 const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
2026020282 globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
2026120283 anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
20284+ }
2026220285
20263- // If we have specified that we are importing helpers, we should report global
20264- // errors if we cannot resolve the helpers external module, or if it does not have
20265- // the necessary helpers exported.
20266- if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) {
20267- // Find the first reference to the helpers module.
20268- const helpersModule = resolveExternalModule(
20269- firstFileRequestingExternalHelpers,
20270- externalHelpersModuleNameText,
20271- Diagnostics.Cannot_find_module_0,
20272- /*errorNode*/ undefined);
20273-
20274- // If we found the module, report errors if it does not have the necessary exports.
20275- if (helpersModule) {
20276- const exports = helpersModule.exports;
20277- if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
20278- verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
20279- }
20280- if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute &&
20281- (languageVersion < ScriptTarget.ESNext || compilerOptions.jsx === JsxEmit.React)) {
20282- verifyHelperSymbol(exports, "__assign", SymbolFlags.Value);
20283- }
20284- if (languageVersion < ScriptTarget.ESNext && requestedExternalEmitHelpers & NodeFlags.HasRestAttribute) {
20285- verifyHelperSymbol(exports, "__rest", SymbolFlags.Value);
20286- }
20287- if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) {
20288- verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value);
20289- if (compilerOptions.emitDecoratorMetadata) {
20290- verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value);
20291- }
20292- }
20293- if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) {
20294- verifyHelperSymbol(exports, "__param", SymbolFlags.Value);
20295- }
20296- if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
20297- verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
20298- if (languageVersion < ScriptTarget.ES2015) {
20299- verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
20286+ function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
20287+ if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
20288+ const sourceFile = getSourceFileOfNode(location);
20289+ if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
20290+ const helpersModule = resolveHelpersModule(sourceFile, location);
20291+ if (helpersModule !== unknownSymbol) {
20292+ const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
20293+ for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) {
20294+ if (uncheckedHelpers & helper) {
20295+ const name = getHelperName(helper);
20296+ const symbol = getSymbol(helpersModule.exports, escapeIdentifier(name), SymbolFlags.Value);
20297+ if (!symbol) {
20298+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
20299+ }
20300+ }
2030020301 }
2030120302 }
20303+ requestedExternalEmitHelpers |= helpers;
2030220304 }
2030320305 }
2030420306 }
2030520307
20306- function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) {
20307- const symbol = getSymbol(symbols, escapeIdentifier(name), meaning);
20308- if (!symbol) {
20309- error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
20308+ function getHelperName(helper: ExternalEmitHelpers) {
20309+ switch (helper) {
20310+ case ExternalEmitHelpers.Extends: return "__extends";
20311+ case ExternalEmitHelpers.Assign: return "__assign";
20312+ case ExternalEmitHelpers.Rest: return "__rest";
20313+ case ExternalEmitHelpers.Decorate: return "__decorate";
20314+ case ExternalEmitHelpers.Metadata: return "__metadata";
20315+ case ExternalEmitHelpers.Param: return "__param";
20316+ case ExternalEmitHelpers.Awaiter: return "__awaiter";
20317+ case ExternalEmitHelpers.Generator: return "__generator";
2031020318 }
2031120319 }
2031220320
20321+ function resolveHelpersModule(node: SourceFile, errorNode: Node) {
20322+ if (!externalHelpersModule) {
20323+ externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
20324+ }
20325+ return externalHelpersModule;
20326+ }
20327+
20328+
2031320329 function createInstantiatedPromiseLikeType(): ObjectType {
2031420330 const promiseLikeType = getGlobalPromiseLikeType();
2031520331 if (promiseLikeType !== emptyGenericType) {
0 commit comments