Skip to content

Commit d3d4f83

Browse files
author
Andy
authored
Remove hack to get target of GetAccessor symbol (#27868)
* Remove hack to get target of GetAccessor symbol * Add tests and get moveToNewFile to work with binding patterns
1 parent 02c7498 commit d3d4f83

File tree

7 files changed

+113
-16
lines changed

7 files changed

+113
-16
lines changed

src/harness/fourslash.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,8 +1328,10 @@ Actual: ${stringify(fullActual)}`);
13281328
})));
13291329
}
13301330

1331-
public verifyQuickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
1332-
this.goToMarker(markerName);
1331+
public verifyQuickInfoAt(markerName: string | Range, expectedText: string, expectedDocumentation?: string) {
1332+
if (typeof markerName === "string") this.goToMarker(markerName);
1333+
else this.goToRangeStart(markerName);
1334+
13331335
this.verifyQuickInfoString(expectedText, expectedDocumentation);
13341336
}
13351337

@@ -4221,7 +4223,7 @@ namespace FourSlashInterface {
42214223
this.state.verifyQuickInfoString(expectedText, expectedDocumentation);
42224224
}
42234225

4224-
public quickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
4226+
public quickInfoAt(markerName: string | FourSlash.Range, expectedText: string, expectedDocumentation?: string) {
42254227
this.state.verifyQuickInfoAt(markerName, expectedText, expectedDocumentation);
42264228
}
42274229

src/services/refactors/moveToNewFile.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ namespace ts.refactor {
612612
| ImportEqualsDeclaration;
613613
type TopLevelDeclarationStatement = NonVariableTopLevelDeclaration | VariableStatement;
614614
interface TopLevelVariableDeclaration extends VariableDeclaration { parent: VariableDeclarationList & { parent: VariableStatement; }; }
615-
type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration;
615+
type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration | BindingElement;
616616
function isTopLevelDeclaration(node: Node): node is TopLevelDeclaration {
617617
return isNonVariableTopLevelDeclaration(node) && isSourceFile(node.parent) || isVariableDeclaration(node) && isSourceFile(node.parent.parent.parent);
618618
}
@@ -653,7 +653,7 @@ namespace ts.refactor {
653653
return cb(statement as FunctionDeclaration | ClassDeclaration | EnumDeclaration | ModuleDeclaration | TypeAliasDeclaration | InterfaceDeclaration | ImportEqualsDeclaration);
654654

655655
case SyntaxKind.VariableStatement:
656-
return forEach((statement as VariableStatement).declarationList.declarations as ReadonlyArray<TopLevelVariableDeclaration>, cb);
656+
return firstDefined((statement as VariableStatement).declarationList.declarations, decl => forEachTopLevelDeclarationInBindingName(decl.name, cb));
657657

658658
case SyntaxKind.ExpressionStatement: {
659659
const { expression } = statement as ExpressionStatement;
@@ -663,13 +663,32 @@ namespace ts.refactor {
663663
}
664664
}
665665
}
666+
function forEachTopLevelDeclarationInBindingName<T>(name: BindingName, cb: (node: TopLevelDeclaration) => T): T | undefined {
667+
switch (name.kind) {
668+
case SyntaxKind.Identifier:
669+
return cb(cast(name.parent, (x): x is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(x) || isBindingElement(x)));
670+
case SyntaxKind.ArrayBindingPattern:
671+
case SyntaxKind.ObjectBindingPattern:
672+
return firstDefined(name.elements, em => isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb));
673+
default:
674+
return Debug.assertNever(name);
675+
}
676+
}
666677

667678
function nameOfTopLevelDeclaration(d: TopLevelDeclaration): Identifier | undefined {
668-
return d.kind === SyntaxKind.ExpressionStatement ? d.expression.left.name : tryCast(d.name, isIdentifier);
679+
return isExpressionStatement(d) ? d.expression.left.name : tryCast(d.name, isIdentifier);
669680
}
670681

671682
function getTopLevelDeclarationStatement(d: TopLevelDeclaration): TopLevelDeclarationStatement {
672-
return isVariableDeclaration(d) ? d.parent.parent : d;
683+
switch (d.kind) {
684+
case SyntaxKind.VariableDeclaration:
685+
return d.parent.parent;
686+
case SyntaxKind.BindingElement:
687+
return getTopLevelDeclarationStatement(
688+
cast(d.parent.parent, (p): p is TopLevelVariableDeclaration | BindingElement => isVariableDeclaration(p) || isBindingElement(p)));
689+
default:
690+
return d;
691+
}
673692
}
674693

675694
function addExportToChanges(sourceFile: SourceFile, decl: TopLevelDeclarationStatement, changes: textChanges.ChangeTracker, useEs6Exports: boolean): void {

src/services/utilities.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,15 +1337,9 @@ namespace ts {
13371337
!bindingElement.propertyName;
13381338
}
13391339

1340-
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName) {
1340+
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName): Symbol | undefined {
13411341
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
1342-
const propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
1343-
if (propSymbol && propSymbol.flags & SymbolFlags.Accessor) {
1344-
// See GH#16922
1345-
Debug.assert(!!(propSymbol.flags & SymbolFlags.Transient));
1346-
return (propSymbol as TransientSymbol).target;
1347-
}
1348-
return propSymbol;
1342+
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
13491343
}
13501344

13511345
/**
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @noLib: true
4+
5+
// @Filename: /a.ts
6+
////class C {
7+
//// get [|{| "isWriteAccess": true, "isDefinition": true |}g|](): number { return 0; }
8+
////
9+
//// set [|{| "isWriteAccess": true, "isDefinition": true |}s|](value: number) {}
10+
////}
11+
////const { [|{| "isWriteAccess": true, "isDefinition": true |}g|], [|{| "isWriteAccess": true, "isDefinition": true |}s|] } = new C();
12+
13+
const [g0, s0, g1, s1] = test.ranges();
14+
verify.quickInfoAt(g0, "(property) C.g: number");
15+
verify.referenceGroups(g0, [{ definition: "(property) C.g: number", ranges: [g0, g1] }]);
16+
verify.referenceGroups(g1, [
17+
{ definition: "(property) C.g: number", ranges: [g0] },
18+
{ definition: "const g: number", ranges: [g1] },
19+
]);
20+
21+
verify.quickInfoAt(s0, "(property) C.s: number");
22+
verify.referenceGroups(s0, [{ definition: "(property) C.s: number", ranges: [s0, s1] }]);
23+
verify.referenceGroups(s1, [
24+
{ definition: "(property) C.s: number", ranges: [s0] },
25+
{ definition: "const s: number", ranges: [s1] }
26+
]);

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ declare namespace FourSlashInterface {
322322
/** Verify the quick info available at the current marker. */
323323
quickInfoIs(expectedText: string, expectedDocumentation?: string): void;
324324
/** Goto a marker and call `quickInfoIs`. */
325-
quickInfoAt(markerName: string, expectedText?: string, expectedDocumentation?: string): void;
325+
quickInfoAt(markerName: string | Range, expectedText?: string, expectedDocumentation?: string): void;
326326
/**
327327
* Call `quickInfoAt` for each pair in the object.
328328
* (If the value is an array, it is [expectedText, expectedDocumentation].)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @Filename: /a.ts
4+
////[|export const [x, { p: y }] = [0, { p: 1 }];|]
5+
6+
// @Filename: /b.ts
7+
////import { x, y } from "./a";
8+
9+
verify.noErrors();
10+
11+
verify.moveToNewFile({
12+
newFileContents: {
13+
"/a.ts": "",
14+
15+
"/x.ts":
16+
`export const [x, { p: y }] = [0, { p: 1 }];`,
17+
18+
"/b.ts":
19+
`
20+
import { x, y } from "./x";
21+
`,
22+
},
23+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @Filename: /a.ts
4+
////class C {
5+
//// get g() { return 0; }
6+
//// get h() { return 1; }
7+
////}
8+
////[|export const { g, h: i } = new C();|]
9+
10+
// @Filename: /b.ts
11+
////import { g, i } from "./a";
12+
13+
verify.noErrors();
14+
15+
verify.moveToNewFile({
16+
newFileContents: {
17+
"/a.ts":
18+
`export class C {
19+
get g() { return 0; }
20+
get h() { return 1; }
21+
}
22+
`,
23+
24+
"/g.ts":
25+
`import { C } from "./a";
26+
export const { g, h: i } = new C();`,
27+
28+
"/b.ts":
29+
`
30+
import { g, i } from "./g";
31+
`,
32+
},
33+
});

0 commit comments

Comments
 (0)