@@ -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();
@@ -11461,6 +11463,9 @@ namespace ts {
11461
11463
member = prop;
11462
11464
}
11463
11465
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
11466
+ if (languageVersion < ScriptTarget.ESNext) {
11467
+ checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
11468
+ }
11464
11469
if (propertiesArray.length > 0) {
11465
11470
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
11466
11471
propertiesArray = [];
@@ -11654,6 +11659,9 @@ namespace ts {
11654
11659
}
11655
11660
11656
11661
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
11662
+ if (compilerOptions.jsx === JsxEmit.React) {
11663
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Assign);
11664
+ }
11657
11665
const type = checkExpression(node.expression);
11658
11666
const props = getPropertiesOfType(type);
11659
11667
for (const prop of props) {
@@ -14419,6 +14427,9 @@ namespace ts {
14419
14427
}
14420
14428
}
14421
14429
else if (property.kind === SyntaxKind.SpreadAssignment) {
14430
+ if (languageVersion < ScriptTarget.ESNext) {
14431
+ checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest);
14432
+ }
14422
14433
const nonRestNames: PropertyName[] = [];
14423
14434
if (allProperties) {
14424
14435
for (let i = 0; i < allProperties.length - 1; i++) {
@@ -15331,6 +15342,13 @@ namespace ts {
15331
15342
checkGrammarFunctionLikeDeclaration(<FunctionLikeDeclaration>node);
15332
15343
}
15333
15344
15345
+ if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) {
15346
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
15347
+ if (languageVersion < ScriptTarget.ES2015) {
15348
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
15349
+ }
15350
+ }
15351
+
15334
15352
checkTypeParameters(node.typeParameters);
15335
15353
15336
15354
forEach(node.parameters, checkParameter);
@@ -16466,7 +16484,15 @@ namespace ts {
16466
16484
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);
16467
16485
}
16468
16486
16487
+ const firstDecorator = node.decorators[0];
16488
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate);
16489
+ if (node.kind === SyntaxKind.Parameter) {
16490
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param);
16491
+ }
16492
+
16469
16493
if (compilerOptions.emitDecoratorMetadata) {
16494
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
16495
+
16470
16496
// we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
16471
16497
switch (node.kind) {
16472
16498
case SyntaxKind.ClassDeclaration:
@@ -16853,7 +16879,7 @@ namespace ts {
16853
16879
}
16854
16880
16855
16881
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
16856
- if (!needCollisionCheckForIdentifier(node, name, "Promise")) {
16882
+ if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
16857
16883
return;
16858
16884
}
16859
16885
@@ -17030,6 +17056,9 @@ namespace ts {
17030
17056
}
17031
17057
17032
17058
if (node.kind === SyntaxKind.BindingElement) {
17059
+ if (node.parent.kind === SyntaxKind.ObjectBindingPattern && languageVersion < ScriptTarget.ESNext) {
17060
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest);
17061
+ }
17033
17062
// check computed properties inside property names of binding elements
17034
17063
if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) {
17035
17064
checkComputedPropertyName(<ComputedPropertyName>node.propertyName);
@@ -17947,6 +17976,10 @@ namespace ts {
17947
17976
17948
17977
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
17949
17978
if (baseTypeNode) {
17979
+ if (languageVersion < ScriptTarget.ES2015) {
17980
+ checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends);
17981
+ }
17982
+
17950
17983
const baseTypes = getBaseTypes(type);
17951
17984
if (baseTypes.length && produceDiagnostics) {
17952
17985
const baseType = baseTypes[0];
@@ -20387,8 +20420,6 @@ namespace ts {
20387
20420
20388
20421
// Initialize global symbol table
20389
20422
let augmentations: LiteralExpression[][];
20390
- let requestedExternalEmitHelpers: NodeFlags = 0;
20391
- let firstFileRequestingExternalHelpers: SourceFile;
20392
20423
for (const file of host.getSourceFiles()) {
20393
20424
if (!isExternalOrCommonJsModule(file)) {
20394
20425
mergeSymbolTable(globals, file.locals);
@@ -20408,15 +20439,6 @@ namespace ts {
20408
20439
}
20409
20440
}
20410
20441
}
20411
- if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) {
20412
- const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags;
20413
- if (fileRequestedExternalEmitHelpers) {
20414
- requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers;
20415
- if (firstFileRequestingExternalHelpers === undefined) {
20416
- firstFileRequestingExternalHelpers = file;
20417
- }
20418
- }
20419
- }
20420
20442
}
20421
20443
20422
20444
if (augmentations) {
@@ -20482,57 +20504,51 @@ namespace ts {
20482
20504
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
20483
20505
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
20484
20506
anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
20507
+ }
20485
20508
20486
- // If we have specified that we are importing helpers, we should report global
20487
- // errors if we cannot resolve the helpers external module, or if it does not have
20488
- // the necessary helpers exported.
20489
- if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) {
20490
- // Find the first reference to the helpers module.
20491
- const helpersModule = resolveExternalModule(
20492
- firstFileRequestingExternalHelpers,
20493
- externalHelpersModuleNameText,
20494
- Diagnostics.Cannot_find_module_0,
20495
- /*errorNode*/ undefined);
20496
-
20497
- // If we found the module, report errors if it does not have the necessary exports.
20498
- if (helpersModule) {
20499
- const exports = helpersModule.exports;
20500
- if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
20501
- verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
20502
- }
20503
- if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute &&
20504
- (languageVersion < ScriptTarget.ESNext || compilerOptions.jsx === JsxEmit.React)) {
20505
- verifyHelperSymbol(exports, "__assign", SymbolFlags.Value);
20506
- }
20507
- if (languageVersion < ScriptTarget.ESNext && requestedExternalEmitHelpers & NodeFlags.HasRestAttribute) {
20508
- verifyHelperSymbol(exports, "__rest", SymbolFlags.Value);
20509
- }
20510
- if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) {
20511
- verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value);
20512
- if (compilerOptions.emitDecoratorMetadata) {
20513
- verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value);
20514
- }
20515
- }
20516
- if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) {
20517
- verifyHelperSymbol(exports, "__param", SymbolFlags.Value);
20518
- }
20519
- if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
20520
- verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
20521
- if (languageVersion < ScriptTarget.ES2015) {
20522
- verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
20509
+ function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
20510
+ if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
20511
+ const sourceFile = getSourceFileOfNode(location);
20512
+ if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
20513
+ const helpersModule = resolveHelpersModule(sourceFile, location);
20514
+ if (helpersModule !== unknownSymbol) {
20515
+ const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
20516
+ for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) {
20517
+ if (uncheckedHelpers & helper) {
20518
+ const name = getHelperName(helper);
20519
+ const symbol = getSymbol(helpersModule.exports, escapeIdentifier(name), SymbolFlags.Value);
20520
+ if (!symbol) {
20521
+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
20522
+ }
20523
+ }
20523
20524
}
20524
20525
}
20526
+ requestedExternalEmitHelpers |= helpers;
20525
20527
}
20526
20528
}
20527
20529
}
20528
20530
20529
- function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) {
20530
- const symbol = getSymbol(symbols, escapeIdentifier(name), meaning);
20531
- if (!symbol) {
20532
- error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name);
20531
+ function getHelperName(helper: ExternalEmitHelpers) {
20532
+ switch (helper) {
20533
+ case ExternalEmitHelpers.Extends: return "__extends";
20534
+ case ExternalEmitHelpers.Assign: return "__assign";
20535
+ case ExternalEmitHelpers.Rest: return "__rest";
20536
+ case ExternalEmitHelpers.Decorate: return "__decorate";
20537
+ case ExternalEmitHelpers.Metadata: return "__metadata";
20538
+ case ExternalEmitHelpers.Param: return "__param";
20539
+ case ExternalEmitHelpers.Awaiter: return "__awaiter";
20540
+ case ExternalEmitHelpers.Generator: return "__generator";
20533
20541
}
20534
20542
}
20535
20543
20544
+ function resolveHelpersModule(node: SourceFile, errorNode: Node) {
20545
+ if (!externalHelpersModule) {
20546
+ externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
20547
+ }
20548
+ return externalHelpersModule;
20549
+ }
20550
+
20551
+
20536
20552
function createInstantiatedPromiseLikeType(): ObjectType {
20537
20553
const promiseLikeType = getGlobalPromiseLikeType();
20538
20554
if (promiseLikeType !== emptyGenericType) {
0 commit comments