Skip to content

Commit 439c14f

Browse files
Merge pull request microsoft#3636 from Microsoft/semanticBindingPropNames
Enable semantic operations on binding element property names
2 parents 81711f9 + ca3c14f commit 439c14f

File tree

45 files changed

+407
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+407
-18
lines changed

src/compiler/checker.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,20 +2307,24 @@ namespace ts {
23072307
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
23082308
return anyType;
23092309
}
2310+
23102311
if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
23112312
// checkRightHandSideOfForOf will return undefined if the for-of expression type was
23122313
// missing properties/signatures required to get its iteratedType (like
23132314
// [Symbol.iterator] or next). This may be because we accessed properties from anyType,
23142315
// or it may have led to an error inside getElementTypeOfIterable.
23152316
return checkRightHandSideOfForOf((<ForOfStatement>declaration.parent.parent).expression) || anyType;
23162317
}
2318+
23172319
if (isBindingPattern(declaration.parent)) {
23182320
return getTypeForBindingElement(<BindingElement>declaration);
23192321
}
2322+
23202323
// Use type from type annotation if one is present
23212324
if (declaration.type) {
23222325
return getTypeFromTypeNode(declaration.type);
23232326
}
2327+
23242328
if (declaration.kind === SyntaxKind.Parameter) {
23252329
let func = <FunctionLikeDeclaration>declaration.parent;
23262330
// For a parameter of a set accessor, use the type of the get accessor if one is present
@@ -2336,14 +2340,22 @@ namespace ts {
23362340
return type;
23372341
}
23382342
}
2343+
23392344
// Use the type of the initializer expression if one is present
23402345
if (declaration.initializer) {
23412346
return checkExpressionCached(declaration.initializer);
23422347
}
2348+
23432349
// If it is a short-hand property assignment, use the type of the identifier
23442350
if (declaration.kind === SyntaxKind.ShorthandPropertyAssignment) {
23452351
return checkIdentifier(<Identifier>declaration.name);
23462352
}
2353+
2354+
// If the declaration specifies a binding pattern, use the type implied by the binding pattern
2355+
if (isBindingPattern(declaration.name)) {
2356+
return getTypeFromBindingPattern(<BindingPattern>declaration.name);
2357+
}
2358+
23472359
// No type specified and nothing can be inferred
23482360
return undefined;
23492361
}
@@ -2429,13 +2441,10 @@ namespace ts {
24292441
// tools see the actual type.
24302442
return declaration.kind !== SyntaxKind.PropertyAssignment ? getWidenedType(type) : type;
24312443
}
2432-
// If no type was specified and nothing could be inferred, and if the declaration specifies a binding pattern, use
2433-
// the type implied by the binding pattern
2434-
if (isBindingPattern(declaration.name)) {
2435-
return getTypeFromBindingPattern(<BindingPattern>declaration.name);
2436-
}
2444+
24372445
// Rest parameters default to type any[], other parameters default to type any
24382446
type = declaration.dotDotDotToken ? anyArrayType : anyType;
2447+
24392448
// Report implicit any errors unless this is a private property within an ambient declaration
24402449
if (reportErrors && compilerOptions.noImplicitAny) {
24412450
let root = getRootDeclaration(declaration);
@@ -13670,10 +13679,22 @@ namespace ts {
1367013679
return getSymbolOfNode(node.parent);
1367113680
}
1367213681

13673-
if (node.kind === SyntaxKind.Identifier && isInRightSideOfImportOrExportAssignment(<Identifier>node)) {
13674-
return node.parent.kind === SyntaxKind.ExportAssignment
13675-
? getSymbolOfEntityNameOrPropertyAccessExpression(<Identifier>node)
13676-
: getSymbolOfPartOfRightHandSideOfImportEquals(<Identifier>node);
13682+
if (node.kind === SyntaxKind.Identifier) {
13683+
if (isInRightSideOfImportOrExportAssignment(<Identifier>node)) {
13684+
return node.parent.kind === SyntaxKind.ExportAssignment
13685+
? getSymbolOfEntityNameOrPropertyAccessExpression(<Identifier>node)
13686+
: getSymbolOfPartOfRightHandSideOfImportEquals(<Identifier>node);
13687+
}
13688+
else if (node.parent.kind === SyntaxKind.BindingElement &&
13689+
node.parent.parent.kind === SyntaxKind.ObjectBindingPattern &&
13690+
node === (<BindingElement>node.parent).propertyName) {
13691+
let typeOfPattern = getTypeAtLocation(node.parent.parent);
13692+
let propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (<Identifier>node).text);
13693+
13694+
if (propertyDeclaration) {
13695+
return propertyDeclaration;
13696+
}
13697+
}
1367713698
}
1367813699

1367913700
switch (node.kind) {

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ namespace ts {
568568
}
569569
}
570570

571-
export function isVariableLike(node: Node): boolean {
571+
export function isVariableLike(node: Node): node is VariableLikeDeclaration {
572572
if (node) {
573573
switch (node.kind) {
574574
case SyntaxKind.BindingElement:

src/harness/fourslash.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -671,20 +671,20 @@ module FourSlash {
671671

672672
let completions = this.getCompletionListAtCaret();
673673
if ((!completions || completions.entries.length === 0) && negative) {
674-
this.raiseError("Completion list is empty at Caret");
675-
} else if ((completions && completions.entries.length !== 0) && !negative) {
676-
674+
this.raiseError("Completion list is empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition);
675+
}
676+
else if (completions && completions.entries.length !== 0 && !negative) {
677677
let errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name;
678678
for (let i = 1; i < completions.entries.length; i++) {
679679
errorMsg += ", " + completions.entries[i].name;
680680
}
681681
errorMsg += "]\n";
682682

683-
Harness.IO.log(errorMsg);
684-
this.raiseError("Completion list is not empty at Caret");
683+
this.raiseError("Completion list is not empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition + errorMsg);
685684
}
686685
}
687686

687+
688688
public verifyCompletionListAllowsNewIdentifier(negative: boolean) {
689689
let completions = this.getCompletionListAtCaret();
690690

src/services/services.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,8 +3234,19 @@ namespace ts {
32343234
// We are *only* completing on properties from the type being destructured.
32353235
isNewIdentifierLocation = false;
32363236

3237-
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
3238-
existingMembers = (<BindingPattern>objectLikeContainer).elements;
3237+
let rootDeclaration = getRootDeclaration(objectLikeContainer.parent);
3238+
if (isVariableLike(rootDeclaration)) {
3239+
// We don't want to complete using the type acquired by the shape
3240+
// of the binding pattern; we are only interested in types acquired
3241+
// through type declaration or inference.
3242+
if (rootDeclaration.initializer || rootDeclaration.type) {
3243+
typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
3244+
existingMembers = (<BindingPattern>objectLikeContainer).elements;
3245+
}
3246+
}
3247+
else {
3248+
Debug.fail("Root declaration is not variable-like.")
3249+
}
32393250
}
32403251
else {
32413252
Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);

tests/baselines/reference/arrowFunctionExpressions.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ var p6 = ({ a }) => { };
7070

7171
var p7 = ({ a: { b } }) => { };
7272
>p7 : Symbol(p7, Decl(arrowFunctionExpressions.ts, 21, 3))
73+
>a : Symbol(a)
7374
>b : Symbol(b, Decl(arrowFunctionExpressions.ts, 21, 16))
7475

7576
var p8 = ({ a = 1 }) => { };
@@ -78,6 +79,7 @@ var p8 = ({ a = 1 }) => { };
7879

7980
var p9 = ({ a: { b = 1 } = { b: 1 } }) => { };
8081
>p9 : Symbol(p9, Decl(arrowFunctionExpressions.ts, 23, 3))
82+
>a : Symbol(a)
8183
>b : Symbol(b, Decl(arrowFunctionExpressions.ts, 23, 16))
8284
>b : Symbol(b, Decl(arrowFunctionExpressions.ts, 23, 28))
8385

tests/baselines/reference/declarationEmitDestructuring1.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { }
2323
function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { }
2424
>baz : Symbol(baz, Decl(declarationEmitDestructuring1.ts, 2, 77))
2525
>a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 14))
26+
>b2 : Symbol(b2, Decl(declarationEmitDestructuring1.ts, 3, 46))
2627
>b1 : Symbol(b1, Decl(declarationEmitDestructuring1.ts, 3, 23))
2728
>c1 : Symbol(c1, Decl(declarationEmitDestructuring1.ts, 3, 26))
2829
>a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 34))

tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello"
1717
>a2 : Symbol(a2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 5))
1818
>b2 : Symbol(b2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 10))
1919
>x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 15))
20+
>y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 91))
2021
>c2 : Symbol(c2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 20))
2122
>x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 41))
2223
>y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 50))

tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,33 @@ var { x6, y6 } = { x6: 5, y6: "hello" };
2121
>y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 4, 25))
2222

2323
var { x7: a1 } = { x7: 5, y7: "hello" };
24+
>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18))
2425
>a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 5))
2526
>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18))
2627
>y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 25))
2728

2829
var { y8: b1 } = { x8: 5, y8: "hello" };
30+
>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25))
2931
>b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 5))
3032
>x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 18))
3133
>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25))
3234

3335
var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" };
36+
>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26))
3437
>a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 5))
38+
>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33))
3539
>b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 13))
3640
>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26))
3741
>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33))
3842

3943
var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } };
44+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46))
4045
>x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 5))
46+
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52))
47+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 57))
4148
>y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 18))
49+
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 69))
50+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 74))
4251
>z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 31))
4352
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46))
4453
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52))

tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,21 @@ var { x6, y6 } = { x6: 5, y6: "hello" };
2121
>y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 4, 25))
2222

2323
var { x7: a1 } = { x7: 5, y7: "hello" };
24+
>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18))
2425
>a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 5))
2526
>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18))
2627
>y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 25))
2728

2829
var { y8: b1 } = { x8: 5, y8: "hello" };
30+
>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25))
2931
>b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 5))
3032
>x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 18))
3133
>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25))
3234

3335
var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" };
36+
>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26))
3437
>a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 5))
38+
>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33))
3539
>b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 13))
3640
>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26))
3741
>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33))

tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
=== tests/cases/compiler/declarationEmitDestructuringObjectLiteralPattern2.ts ===
22

33
var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } };
4+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46))
45
>x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 5))
6+
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52))
7+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 57))
58
>y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 18))
9+
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 69))
10+
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 74))
611
>z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 31))
712
>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46))
813
>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52))

0 commit comments

Comments
 (0)