@@ -38,6 +38,8 @@ namespace ts {
38
38
// is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
39
39
// they no longer need the information (for example, if the user started editing again).
40
40
let cancellationToken: CancellationToken;
41
+ let requestedExternalEmitHelpers: ExternalEmitHelpers;
42
+ let externalHelpersModule: Symbol;
41
43
42
44
const Symbol = objectAllocator.getSymbolConstructor();
43
45
const Type = objectAllocator.getTypeConstructor();
@@ -11272,6 +11274,9 @@ namespace ts {
11272
11274
member = prop;
11273
11275
}
11274
11276
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
11277
+ if (languageVersion < ScriptTarget.ESNext) {
11278
+ checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
11279
+ }
11275
11280
if (propertiesArray.length > 0) {
11276
11281
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
11277
11282
propertiesArray = [];
@@ -11459,6 +11464,9 @@ namespace ts {
11459
11464
}
11460
11465
11461
11466
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
11467
+ if (compilerOptions.jsx === JsxEmit.React) {
11468
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Assign);
11469
+ }
11462
11470
const type = checkExpression(node.expression);
11463
11471
const props = getPropertiesOfType(type);
11464
11472
for (const prop of props) {
@@ -14223,6 +14231,9 @@ namespace ts {
14223
14231
}
14224
14232
}
14225
14233
else if (property.kind === SyntaxKind.SpreadAssignment) {
14234
+ if (languageVersion < ScriptTarget.ESNext) {
14235
+ checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
14236
+ }
14226
14237
checkReferenceExpression(property.expression, Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access);
14227
14238
}
14228
14239
else {
@@ -15107,6 +15118,13 @@ namespace ts {
15107
15118
checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
15108
15119
}
15109
15120
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
+
15110
15128
checkTypeParameters(node.typeParameters);
15111
15129
15112
15130
forEach(node.parameters, checkParameter);
@@ -16242,7 +16260,15 @@ namespace ts {
16242
16260
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);
16243
16261
}
16244
16262
16263
+ const firstDecorator = node.decorators[0];
16264
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate);
16265
+ if (node.kind === SyntaxKind.Parameter) {
16266
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param);
16267
+ }
16268
+
16245
16269
if (compilerOptions.emitDecoratorMetadata) {
16270
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
16271
+
16246
16272
// we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
16247
16273
switch (node.kind) {
16248
16274
case SyntaxKind.ClassDeclaration:
@@ -16629,7 +16655,7 @@ namespace ts {
16629
16655
}
16630
16656
16631
16657
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
16632
- if (!needCollisionCheckForIdentifier(node, name, "Promise")) {
16658
+ if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
16633
16659
return;
16634
16660
}
16635
16661
@@ -16806,6 +16832,9 @@ namespace ts {
16806
16832
}
16807
16833
16808
16834
if (node.kind === SyntaxKind.BindingElement) {
16835
+ if (node.parent.kind === SyntaxKind.ObjectBindingPattern && languageVersion < ScriptTarget.ESNext) {
16836
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest);
16837
+ }
16809
16838
// check computed properties inside property names of binding elements
16810
16839
if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
16811
16840
checkComputedPropertyName(<ComputedPropertyName>node.propertyName);
@@ -17724,6 +17753,10 @@ namespace ts {
17724
17753
17725
17754
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
17726
17755
if (baseTypeNode) {
17756
+ if (languageVersion < ScriptTarget.ES2015) {
17757
+ checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends);
17758
+ }
17759
+
17727
17760
const baseTypes = getBaseTypes(type);
17728
17761
if (baseTypes.length && produceDiagnostics) {
17729
17762
const baseType = baseTypes[0];
@@ -20164,8 +20197,6 @@ namespace ts {
20164
20197
20165
20198
// Initialize global symbol table
20166
20199
let augmentations: LiteralExpression[][];
20167
- let requestedExternalEmitHelpers: NodeFlags = 0;
20168
- let firstFileRequestingExternalHelpers: SourceFile;
20169
20200
for (const file of host.getSourceFiles()) {
20170
20201
if (!isExternalOrCommonJsModule(file)) {
20171
20202
mergeSymbolTable(globals, file.locals);
@@ -20185,15 +20216,6 @@ namespace ts {
20185
20216
}
20186
20217
}
20187
20218
}
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
- }
20197
20219
}
20198
20220
20199
20221
if (augmentations) {
@@ -20259,57 +20281,51 @@ namespace ts {
20259
20281
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
20260
20282
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
20261
20283
anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
20284
+ }
20262
20285
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
+ }
20300
20301
}
20301
20302
}
20303
+ requestedExternalEmitHelpers |= helpers;
20302
20304
}
20303
20305
}
20304
20306
}
20305
20307
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";
20310
20318
}
20311
20319
}
20312
20320
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
+
20313
20329
function createInstantiatedPromiseLikeType(): ObjectType {
20314
20330
const promiseLikeType = getGlobalPromiseLikeType();
20315
20331
if (promiseLikeType !== emptyGenericType) {
0 commit comments