Skip to content

Commit a677712

Browse files
author
Andy Hanson
committed
Merge branch 'master' into map5
2 parents 2e6f369 + 69e0677 commit a677712

29 files changed

Lines changed: 1229 additions & 47 deletions

src/compiler/binder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,7 @@ namespace ts {
31363136
case SyntaxKind.TaggedTemplateExpression:
31373137
case SyntaxKind.ShorthandPropertyAssignment:
31383138
case SyntaxKind.StaticKeyword:
3139+
case SyntaxKind.MetaProperty:
31393140
// These nodes are ES6 syntax.
31403141
transformFlags |= TransformFlags.AssertES2015;
31413142
break;

src/compiler/checker.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ namespace ts {
241241
const visitedFlowNodes: FlowNode[] = [];
242242
const visitedFlowTypes: FlowType[] = [];
243243
const potentialThisCollisions: Node[] = [];
244+
const potentialNewTargetCollisions: Node[] = [];
244245
const awaitedTypeStack: number[] = [];
245246

246247
const diagnostics = createDiagnosticCollection();
@@ -10368,6 +10369,7 @@ namespace ts {
1036810369

1036910370
checkCollisionWithCapturedSuperVariable(node, node);
1037010371
checkCollisionWithCapturedThisVariable(node, node);
10372+
checkCollisionWithCapturedNewTargetVariable(node, node);
1037110373
checkNestedBlockScopedBinding(node, symbol);
1037210374

1037310375
const type = getTypeOfSymbol(localOrExportSymbol);
@@ -10409,7 +10411,7 @@ namespace ts {
1040910411
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
1041010412
// declaration container are the same).
1041110413
const assumeInitialized = isParameter || isOuterVariable ||
10412-
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0) ||
10414+
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node)) ||
1041310415
isInAmbientContext(declaration);
1041410416
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
1041510417
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
@@ -13893,6 +13895,24 @@ namespace ts {
1389313895
return getNonNullableType(checkExpression(node.expression));
1389413896
}
1389513897

13898+
function checkMetaProperty(node: MetaProperty) {
13899+
checkGrammarMetaProperty(node);
13900+
Debug.assert(node.keywordToken === SyntaxKind.NewKeyword && node.name.text === "target", "Unrecognized meta-property.");
13901+
const container = getNewTargetContainer(node);
13902+
if (!container) {
13903+
error(node, Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
13904+
return unknownType;
13905+
}
13906+
else if (container.kind === SyntaxKind.Constructor) {
13907+
const symbol = getSymbolOfNode(container.parent);
13908+
return getTypeOfSymbol(symbol);
13909+
}
13910+
else {
13911+
const symbol = getSymbolOfNode(container);
13912+
return getTypeOfSymbol(symbol);
13913+
}
13914+
}
13915+
1389613916
function getTypeOfParameter(symbol: Symbol) {
1389713917
const type = getTypeOfSymbol(symbol);
1389813918
if (strictNullChecks) {
@@ -14301,6 +14321,7 @@ namespace ts {
1430114321
if (produceDiagnostics && node.kind !== SyntaxKind.MethodDeclaration) {
1430214322
checkCollisionWithCapturedSuperVariable(node, (<FunctionExpression>node).name);
1430314323
checkCollisionWithCapturedThisVariable(node, (<FunctionExpression>node).name);
14324+
checkCollisionWithCapturedNewTargetVariable(node, (<FunctionExpression>node).name);
1430414325
}
1430514326

1430614327
return type;
@@ -15335,6 +15356,8 @@ namespace ts {
1533515356
return checkAssertion(<AssertionExpression>node);
1533615357
case SyntaxKind.NonNullExpression:
1533715358
return checkNonNullAssertion(<NonNullExpression>node);
15359+
case SyntaxKind.MetaProperty:
15360+
return checkMetaProperty(<MetaProperty>node);
1533815361
case SyntaxKind.DeleteExpression:
1533915362
return checkDeleteExpression(<DeleteExpression>node);
1534015363
case SyntaxKind.VoidExpression:
@@ -16742,6 +16765,7 @@ namespace ts {
1674216765

1674316766
checkCollisionWithCapturedSuperVariable(node, node.name);
1674416767
checkCollisionWithCapturedThisVariable(node, node.name);
16768+
checkCollisionWithCapturedNewTargetVariable(node, node.name);
1674516769
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
1674616770
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
1674716771
}
@@ -17034,6 +17058,12 @@ namespace ts {
1703417058
}
1703517059
}
1703617060

17061+
function checkCollisionWithCapturedNewTargetVariable(node: Node, name: Identifier): void {
17062+
if (needCollisionCheckForIdentifier(node, name, "_newTarget")) {
17063+
potentialNewTargetCollisions.push(node);
17064+
}
17065+
}
17066+
1703717067
// this function will run after checking the source file so 'CaptureThis' is correct for all nodes
1703817068
function checkIfThisIsCapturedInEnclosingScope(node: Node): void {
1703917069
let current = node;
@@ -17052,6 +17082,23 @@ namespace ts {
1705217082
}
1705317083
}
1705417084

17085+
function checkIfNewTargetIsCapturedInEnclosingScope(node: Node): void {
17086+
let current = node;
17087+
while (current) {
17088+
if (getNodeCheckFlags(current) & NodeCheckFlags.CaptureNewTarget) {
17089+
const isDeclaration = node.kind !== SyntaxKind.Identifier;
17090+
if (isDeclaration) {
17091+
error((<Declaration>node).name, Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
17092+
}
17093+
else {
17094+
error(node, Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
17095+
}
17096+
return;
17097+
}
17098+
current = current.parent;
17099+
}
17100+
}
17101+
1705517102
function checkCollisionWithCapturedSuperVariable(node: Node, name: Identifier) {
1705617103
if (!needCollisionCheckForIdentifier(node, name, "_super")) {
1705717104
return;
@@ -17348,6 +17395,7 @@ namespace ts {
1734817395
}
1734917396
checkCollisionWithCapturedSuperVariable(node, <Identifier>node.name);
1735017397
checkCollisionWithCapturedThisVariable(node, <Identifier>node.name);
17398+
checkCollisionWithCapturedNewTargetVariable(node, <Identifier>node.name);
1735117399
checkCollisionWithRequireExportsInGeneratedCode(node, <Identifier>node.name);
1735217400
checkCollisionWithGlobalPromiseInGeneratedCode(node, <Identifier>node.name);
1735317401
}
@@ -18184,6 +18232,7 @@ namespace ts {
1818418232
if (node.name) {
1818518233
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
1818618234
checkCollisionWithCapturedThisVariable(node, node.name);
18235+
checkCollisionWithCapturedNewTargetVariable(node, node.name);
1818718236
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
1818818237
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
1818918238
}
@@ -18719,6 +18768,7 @@ namespace ts {
1871918768

1872018769
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
1872118770
checkCollisionWithCapturedThisVariable(node, node.name);
18771+
checkCollisionWithCapturedNewTargetVariable(node, node.name);
1872218772
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
1872318773
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
1872418774
checkExportsOnMergedDeclarations(node);
@@ -19424,6 +19474,7 @@ namespace ts {
1942419474
checkGrammarSourceFile(node);
1942519475

1942619476
potentialThisCollisions.length = 0;
19477+
potentialNewTargetCollisions.length = 0;
1942719478

1942819479
deferredNodes = [];
1942919480
deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
@@ -19452,6 +19503,11 @@ namespace ts {
1945219503
potentialThisCollisions.length = 0;
1945319504
}
1945419505

19506+
if (potentialNewTargetCollisions.length) {
19507+
forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope)
19508+
potentialNewTargetCollisions.length = 0;
19509+
}
19510+
1945519511
links.flags |= NodeCheckFlags.TypeChecked;
1945619512
}
1945719513
}
@@ -21780,6 +21836,14 @@ namespace ts {
2178021836
}
2178121837
}
2178221838

21839+
function checkGrammarMetaProperty(node: MetaProperty) {
21840+
if (node.keywordToken === SyntaxKind.NewKeyword) {
21841+
if (node.name.text !== "target") {
21842+
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_0, node.name.text, tokenToString(node.keywordToken), "target");
21843+
}
21844+
}
21845+
}
21846+
2178321847
function hasParseDiagnostics(sourceFile: SourceFile): boolean {
2178421848
return sourceFile.parseDiagnostics.length > 0;
2178521849
}

src/compiler/diagnosticMessages.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,14 @@
17751775
"category": "Error",
17761776
"code": 2542
17771777
},
1778+
"Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference.": {
1779+
"category": "Error",
1780+
"code": 2543
1781+
},
1782+
"Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference.": {
1783+
"category": "Error",
1784+
"code": 2544
1785+
},
17781786
"JSX element attributes type '{0}' may not be a union type.": {
17791787
"category": "Error",
17801788
"code": 2600
@@ -3197,6 +3205,14 @@
31973205
"category": "Error",
31983206
"code": 17011
31993207
},
3208+
"'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{0}'?": {
3209+
"category": "Error",
3210+
"code": 17012
3211+
},
3212+
"Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor.": {
3213+
"category": "Error",
3214+
"code": 17013
3215+
},
32003216

32013217
"Circularity detected while resolving configuration: {0}": {
32023218
"category": "Error",

src/compiler/emitter.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,8 @@ namespace ts {
660660
return emitAsExpression(<AsExpression>node);
661661
case SyntaxKind.NonNullExpression:
662662
return emitNonNullExpression(<NonNullExpression>node);
663+
case SyntaxKind.MetaProperty:
664+
return emitMetaProperty(<MetaProperty>node);
663665

664666
// JSX
665667
case SyntaxKind.JsxElement:
@@ -1247,6 +1249,12 @@ namespace ts {
12471249
write("!");
12481250
}
12491251

1252+
function emitMetaProperty(node: MetaProperty) {
1253+
writeToken(node.keywordToken, node.pos);
1254+
write(".");
1255+
emit(node.name);
1256+
}
1257+
12501258
//
12511259
// Misc
12521260
//
@@ -2586,6 +2594,13 @@ namespace ts {
25862594
return makeUniqueName("class");
25872595
}
25882596

2597+
function generateNameForMethodOrAccessor(node: MethodDeclaration | AccessorDeclaration) {
2598+
if (isIdentifier(node.name)) {
2599+
return generateNameForNodeCached(node.name);
2600+
}
2601+
return makeTempVariableName(TempFlags.Auto);
2602+
}
2603+
25892604
/**
25902605
* Generates a unique name from a node.
25912606
*
@@ -2607,6 +2622,10 @@ namespace ts {
26072622
return generateNameForExportDefault();
26082623
case SyntaxKind.ClassExpression:
26092624
return generateNameForClassExpression();
2625+
case SyntaxKind.MethodDeclaration:
2626+
case SyntaxKind.GetAccessor:
2627+
case SyntaxKind.SetAccessor:
2628+
return generateNameForMethodOrAccessor(<MethodDeclaration | AccessorDeclaration>node);
26102629
default:
26112630
return makeTempVariableName(TempFlags.Auto);
26122631
}
@@ -2657,6 +2676,11 @@ namespace ts {
26572676
return node;
26582677
}
26592678

2679+
function generateNameForNodeCached(node: Node) {
2680+
const nodeId = getNodeId(node);
2681+
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node)));
2682+
}
2683+
26602684
/**
26612685
* Gets the generated identifier text from a generated identifier.
26622686
*
@@ -2667,8 +2691,7 @@ namespace ts {
26672691
// Generated names generate unique names based on their original node
26682692
// and are cached based on that node's id
26692693
const node = getNodeForGeneratedName(name);
2670-
const nodeId = getNodeId(node);
2671-
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node)));
2694+
return generateNameForNodeCached(node);
26722695
}
26732696
else {
26742697
// Auto, Loop, and Unique names are cached based on their unique

src/compiler/parser.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ namespace ts {
198198
visitNode(cbNode, (<AsExpression>node).type);
199199
case SyntaxKind.NonNullExpression:
200200
return visitNode(cbNode, (<NonNullExpression>node).expression);
201+
case SyntaxKind.MetaProperty:
202+
return visitNode(cbNode, (<MetaProperty>node).name);
201203
case SyntaxKind.ConditionalExpression:
202204
return visitNode(cbNode, (<ConditionalExpression>node).condition) ||
203205
visitNode(cbNode, (<ConditionalExpression>node).questionToken) ||
@@ -4335,15 +4337,22 @@ namespace ts {
43354337
return isIdentifier() ? parseIdentifier() : undefined;
43364338
}
43374339

4338-
function parseNewExpression(): NewExpression {
4339-
const node = <NewExpression>createNode(SyntaxKind.NewExpression);
4340+
function parseNewExpression(): NewExpression | MetaProperty {
4341+
const fullStart = scanner.getStartPos();
43404342
parseExpected(SyntaxKind.NewKeyword);
4343+
if (parseOptional(SyntaxKind.DotToken)) {
4344+
const node = <MetaProperty>createNode(SyntaxKind.MetaProperty, fullStart);
4345+
node.keywordToken = SyntaxKind.NewKeyword;
4346+
node.name = parseIdentifierName();
4347+
return finishNode(node);
4348+
}
4349+
4350+
const node = <NewExpression>createNode(SyntaxKind.NewExpression, fullStart);
43414351
node.expression = parseMemberExpressionOrHigher();
43424352
node.typeArguments = tryParse(parseTypeArgumentsInExpression);
43434353
if (node.typeArguments || token() === SyntaxKind.OpenParenToken) {
43444354
node.arguments = parseArgumentList();
43454355
}
4346-
43474356
return finishNode(node);
43484357
}
43494358

0 commit comments

Comments
 (0)