Skip to content

Commit 5091bfc

Browse files
author
Andy Hanson
committed
Merge branch 'master' into completionsBracket
2 parents 4f5f540 + 2ea5f58 commit 5091bfc

File tree

42 files changed

+148
-271
lines changed

Some content is hidden

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

42 files changed

+148
-271
lines changed

Diff for: src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace ts.codefix {
2121
});
2222

2323
function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & { left: Identifier } | undefined {
24-
const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isQualifiedName)!;
24+
const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isQualifiedName)!;
2525
Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
2626
return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined;
2727
}

Diff for: src/services/completions.ts

+15-17
Original file line numberDiff line numberDiff line change
@@ -229,26 +229,24 @@ namespace ts.Completions {
229229
// Based on the order we add things we will always see locals first, then globals, then module exports.
230230
// So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
231231
const uniques = createMap<true>();
232-
if (symbols) {
233-
for (const symbol of symbols) {
234-
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
235-
const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, includeInsertTextCompletions);
236-
if (!entry) {
237-
continue;
238-
}
239-
240-
const { name } = entry;
241-
if (uniques.has(name)) {
242-
continue;
243-
}
232+
for (const symbol of symbols) {
233+
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
234+
const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, includeInsertTextCompletions);
235+
if (!entry) {
236+
continue;
237+
}
244238

245-
// Latter case tests whether this is a global variable.
246-
if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) {
247-
uniques.set(name, true);
248-
}
239+
const { name } = entry;
240+
if (uniques.has(name)) {
241+
continue;
242+
}
249243

250-
entries.push(entry);
244+
// Latter case tests whether this is a global variable.
245+
if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) {
246+
uniques.set(name, true);
251247
}
248+
249+
entries.push(entry);
252250
}
253251

254252
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start));

Diff for: src/services/findAllReferences.ts

+19-48
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,10 @@ namespace ts.FindAllReferences {
4343

4444
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
4545
const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
46-
47-
if (!referencedSymbols || !referencedSymbols.length) {
48-
return undefined;
49-
}
50-
51-
const out: ReferencedSymbol[] = [];
5246
const checker = program.getTypeChecker();
53-
for (const { definition, references } of referencedSymbols) {
47+
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) =>
5448
// Only include referenced symbols that have a valid definition.
55-
if (definition) {
56-
out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
57-
}
58-
}
59-
60-
return out;
49+
definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
6150
}
6251

6352
export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ImplementationLocation[] {
@@ -876,6 +865,8 @@ namespace ts.FindAllReferences.Core {
876865
case SpecialSearchKind.Class:
877866
addClassStaticThisReferences(referenceLocation, search, state);
878867
break;
868+
default:
869+
Debug.assertNever(state.specialSearchKind);
879870
}
880871

881872
getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
@@ -1436,7 +1427,7 @@ namespace ts.FindAllReferences.Core {
14361427
// This is not needed when searching for re-exports.
14371428
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] {
14381429
// The search set contains at least the current symbol
1439-
const result = [symbol];
1430+
const result: Symbol[] = [];
14401431

14411432
const containingObjectLiteralElement = getContainingObjectLiteralElement(location);
14421433
if (containingObjectLiteralElement) {
@@ -1453,9 +1444,9 @@ namespace ts.FindAllReferences.Core {
14531444
// If the location is in a context sensitive location (i.e. in an object literal) try
14541445
// to get a contextual type for it, and add the property symbol from the contextual
14551446
// type to the search set
1456-
forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => {
1457-
addRange(result, checker.getRootSymbols(contextualSymbol));
1458-
});
1447+
for (const contextualSymbol of getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker)) {
1448+
addRootSymbols(contextualSymbol);
1449+
}
14591450

14601451
/* Because in short-hand property assignment, location has two meaning : property name and as value of the property
14611452
* When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
@@ -1496,9 +1487,7 @@ namespace ts.FindAllReferences.Core {
14961487
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
14971488
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
14981489
for (const rootSymbol of checker.getRootSymbols(sym)) {
1499-
if (rootSymbol !== sym) {
1500-
result.push(rootSymbol);
1501-
}
1490+
result.push(rootSymbol);
15021491

15031492
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
15041493
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
@@ -1522,7 +1511,7 @@ namespace ts.FindAllReferences.Core {
15221511
* @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
15231512
* The value of previousIterationSymbol is undefined when the function is first called.
15241513
*/
1525-
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void {
1514+
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Push<Symbol>, previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void {
15261515
if (!symbol) {
15271516
return;
15281517
}
@@ -1591,9 +1580,7 @@ namespace ts.FindAllReferences.Core {
15911580
// compare to our searchSymbol
15921581
const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation);
15931582
if (containingObjectLiteralElement) {
1594-
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol =>
1595-
find(checker.getRootSymbols(contextualSymbol), search.includes));
1596-
1583+
const contextualSymbol = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), findRootSymbol);
15971584
if (contextualSymbol) {
15981585
return contextualSymbol;
15991586
}
@@ -1622,7 +1609,7 @@ namespace ts.FindAllReferences.Core {
16221609
function findRootSymbol(sym: Symbol): Symbol | undefined {
16231610
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
16241611
// Or a union property, use its underlying unioned symbols
1625-
return forEach(state.checker.getRootSymbols(sym), rootSymbol => {
1612+
return firstDefined(checker.getRootSymbols(sym), rootSymbol => {
16261613
// if it is in the list, then we are done
16271614
if (search.includes(rootSymbol)) {
16281615
return rootSymbol;
@@ -1633,12 +1620,12 @@ namespace ts.FindAllReferences.Core {
16331620
// parent symbol
16341621
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
16351622
// Parents will only be defined if implementations is true
1636-
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) {
1623+
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))) {
16371624
return undefined;
16381625
}
16391626

16401627
const result: Symbol[] = [];
1641-
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
1628+
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
16421629
return find(result, search.includes);
16431630
}
16441631

@@ -1660,28 +1647,12 @@ namespace ts.FindAllReferences.Core {
16601647
}
16611648

16621649
/** Gets all symbols for one property. Does not get symbols for every property. */
1663-
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): Symbol[] | undefined {
1664-
const objectLiteral = <ObjectLiteralExpression>node.parent;
1665-
const contextualType = checker.getContextualType(objectLiteral);
1650+
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray<Symbol> {
1651+
const contextualType = checker.getContextualType(<ObjectLiteralExpression>node.parent);
16661652
const name = getNameFromObjectLiteralElement(node);
1667-
if (name && contextualType) {
1668-
const result: Symbol[] = [];
1669-
const symbol = contextualType.getProperty(name);
1670-
if (symbol) {
1671-
result.push(symbol);
1672-
}
1673-
1674-
if (contextualType.flags & TypeFlags.Union) {
1675-
forEach((<UnionType>contextualType).types, t => {
1676-
const symbol = t.getProperty(name);
1677-
if (symbol) {
1678-
result.push(symbol);
1679-
}
1680-
});
1681-
}
1682-
return result;
1683-
}
1684-
return undefined;
1653+
const symbol = contextualType && name && contextualType.getProperty(name);
1654+
return symbol ? [symbol] :
1655+
contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((<UnionType>contextualType).types, t => t.getProperty(name)) : emptyArray;
16851656
}
16861657

16871658
/**

Diff for: tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,5 @@ function checkRefs() {
3636
const ranges = test.ranges();
3737
const [r0, r1] = ranges;
3838
verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]);
39-
verify.referenceGroups(r1, [
40-
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] },
41-
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] }
42-
]);
39+
verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]);
4340
}

Diff for: tests/cases/fourslash/codeFixInPropertyAccess_js.ts

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @checkJs: true
5+
6+
// @Filename: /a.js
7+
//// /**
8+
//// * @typedef Foo
9+
//// * @property foo
10+
//// */
11+
12+
//// /**
13+
//// * @param {Foo.foo} inst
14+
//// */
15+
//// function blah(inst) {
16+
//// return false;
17+
//// }
18+
19+
verify.codeFixAll({
20+
fixId: "correctQualifiedNameToIndexedAccessType",
21+
newFileContent:
22+
`/**
23+
* @typedef Foo
24+
* @property foo
25+
*/
26+
/**
27+
* @param {Foo["foo"]} inst
28+
*/
29+
function blah(inst) {
30+
return false;
31+
}`,
32+
});
33+
34+
35+
/**
36+
* @typedef Foo
37+
* @property foo
38+
*/
39+
40+
/**
41+
* @param {Foo.foo} inst
42+
*/
43+
function blah(inst) {
44+
return false;
45+
}

Diff for: tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,4 @@
88
////
99
////let {[|property|]: pVar} = x;
1010

11-
const ranges = test.ranges();
12-
const [r0, r1, r2] = ranges;
13-
verify.referenceGroups(r0, [{ definition: "(property) property: {}", ranges }]);
14-
verify.referenceGroups([r1, r2], [
15-
{ definition: "(property) property: {}", ranges: [r0] },
16-
{ definition: "(property) property: {}", ranges: [r1, r2] }
17-
]);
11+
verify.singleReferenceGroup("(property) property: {}");

Diff for: tests/cases/fourslash/findAllRefsForObjectSpread.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ verify.referenceGroups(r1, [{ definition: "(property) A2.a: number", ranges: [r1
1616

1717
// but the resulting property refers to everything
1818
verify.referenceGroups(r2, [
19-
{ definition: "(property) A1.a: string", ranges: [r0, r3] },
19+
{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] },
2020
{ definition: "(property) A2.a: number", ranges: [r1] },
21-
{ definition: "(property) a: string | number", ranges: [r2] }
2221
]);
2322

2423
verify.referenceGroups(r3, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]);

Diff for: tests/cases/fourslash/findAllRefsInheritedProperties1.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,5 @@
1010
//// v.[|propName|];
1111

1212
const [r0, r1, r2, r3] = test.ranges();
13-
verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ranges: [r0, r2] }]);
14-
verify.referenceGroups(r2, [
15-
{ definition: "(method) class1.doStuff(): void", ranges: [r0] },
16-
{ definition: "(method) class1.doStuff(): void", ranges: [r2] }
17-
]);
13+
verify.singleReferenceGroup("(method) class1.doStuff(): void", [r0, r2]);
1814
verify.singleReferenceGroup("(property) class1.propName: string", [r1, r3]);

Diff for: tests/cases/fourslash/findAllRefsInheritedProperties3.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ran
2222
verify.referenceGroups(r1, [{ definition: "(property) class1.propName: string", ranges: [r1, r5, r7] }]);
2323
verify.referenceGroups(r2, [{ definition: "(method) interface1.doStuff(): void", ranges: [r2, r4, r6] }]);
2424
verify.referenceGroups(r3, [{ definition: "(property) interface1.propName: string", ranges: [r3, r5, r7] }]);
25-
verify.referenceGroups(r4, [
25+
verify.referenceGroups([r4, r6], [
2626
{ definition: "(method) class1.doStuff(): void", ranges: [r0] },
2727
{ definition: "(method) interface1.doStuff(): void", ranges: [r2] },
2828
{ definition: "(method) class2.doStuff(): void", ranges: [r4, r6] }
@@ -32,9 +32,3 @@ verify.referenceGroups([r5, r7], [
3232
{ definition: "(property) interface1.propName: string", ranges: [r3] },
3333
{ definition: "(property) class2.propName: string", ranges: [r5, r7] }
3434
]);
35-
verify.referenceGroups(r6, [
36-
{ definition: "(method) class1.doStuff(): void", ranges: [r0] },
37-
{ definition: "(method) interface1.doStuff(): void", ranges: [r2] },
38-
{ definition: "(method) class2.doStuff(): void", ranges: [r4] },
39-
{ definition: "(method) class2.doStuff(): void", ranges: [r6] }
40-
]);

Diff for: tests/cases/fourslash/findAllRefsMappedType.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,4 @@
77
////declare const u: U;
88
////u.[|a|];
99

10-
const ranges = test.ranges();
11-
const [r0, r1, r2] = ranges;
12-
verify.referenceGroups([r0, r1], [{ definition: "(property) T.a: number", ranges }]);
13-
verify.referenceGroups(r2, [
14-
{ definition: "(property) T.a: number", ranges: [r0, r1] },
15-
{ definition: "(property) a: string", ranges: [r2] }]);
10+
verify.singleReferenceGroup("(property) T.a: number");

Diff for: tests/cases/fourslash/findAllRefsOnDefinition.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,4 @@
2626
const ranges = test.ranges();
2727
const [r0, r1] = ranges;
2828
verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]);
29-
verify.referenceGroups(r1, [
30-
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] },
31-
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] },
32-
]);
29+
verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @noLib: true
4+
5+
////interface A {
6+
//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number | string;
7+
////}
8+
////interface B extends A {
9+
//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number;
10+
////}
11+
////const a: A = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 };
12+
////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 };
13+
14+
const [r0, r1, r2, r3] = test.ranges();
15+
verify.referenceGroups(r0, [
16+
{ definition: "(property) A.x: string | number", ranges: [r0, r1, r2, r3] },
17+
]);
18+
verify.referenceGroups(r1, [
19+
{ definition: "(property) A.x: string | number", ranges: [r0, r2] },
20+
{ definition: "(property) B.x: number", ranges: [r1, r3] },
21+
]);
22+
verify.referenceGroups(r2, [
23+
{ definition: "(property) A.x: string | number", ranges: [r0, r1, r3] },
24+
{ definition: "(property) x: number", ranges: [r2] },
25+
]);
26+
verify.referenceGroups(r3, [
27+
{ definition: "(property) A.x: string | number", ranges: [r0, r2] },
28+
{ definition: "(property) B.x: number", ranges: [r1] },
29+
{ definition: "(property) x: number", ranges: [r3] },
30+
]);

Diff for: tests/cases/fourslash/findAllRefsRootSymbols.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ verify.referenceGroups(r0, [{ definition: "(property) I.x: {}", ranges: [r0, r3]
1010
verify.referenceGroups(r1, [{ definition: "(property) J.x: {}", ranges: [r1, r3] }]);
1111
verify.referenceGroups(r2, [{ definition: "(property) x: string", ranges: [r2, r3] }]);
1212
verify.referenceGroups(r3, [
13-
{ definition: "(property) I.x: {}", ranges: [r0] },
13+
{ definition: "(property) I.x: {}", ranges: [r0, r3] },
1414
{ definition: "(property) J.x: {}", ranges: [r1] },
1515
{ definition: "(property) x: string", ranges: [r2] },
16-
{ definition: "(property) x: string & {}", ranges: [r3] },
1716
]);

Diff for: tests/cases/fourslash/findAllRefsThisKeyword.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,4 @@ verify.referenceGroups(g0, [{ definition: "(parameter) this: any", ranges: [g0,
3232
verify.referenceGroups(g1, [{ definition: "this: any", ranges: [g0, g1] }]);
3333
verify.singleReferenceGroup("this: typeof C", [x, y]);
3434
verify.singleReferenceGroup("this: this", [constructor, method]);
35-
verify.referenceGroups(propDef, [{ definition: "(property) this: number", ranges: [propDef, propUse] }]);
36-
verify.referenceGroups(propUse, [
37-
{ definition: "(property) this: number", ranges: [propDef] },
38-
{ definition: "(property) this: number", ranges: [propUse] },
39-
]);
35+
verify.singleReferenceGroup("(property) this: number", [propDef, propUse]);

Diff for: tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,4 @@
77
////var x: Foo;
88
////x.[|_bar|];
99

10-
const ranges = test.ranges();
11-
const [r0, r1] = ranges;
12-
verify.referenceGroups(r0, [{ definition: "(method) Foo._bar(): number", ranges }]);
13-
verify.referenceGroups(r1, [
14-
{ definition: "(method) Foo._bar(): number", ranges: [r0] },
15-
{ definition: "(method) Foo._bar(): number", ranges: [r1] }
16-
]);
10+
verify.singleReferenceGroup("(method) Foo._bar(): number");

Diff for: tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,4 @@
77
////var x: Foo;
88
////x.[|__bar|];
99

10-
const ranges = test.ranges();
11-
const [r0, r1] = ranges;
12-
verify.referenceGroups(r0, [{ definition: "(method) Foo.__bar(): number", ranges }]);
13-
verify.referenceGroups(r1, [
14-
{ definition: "(method) Foo.__bar(): number", ranges: [r0] },
15-
{ definition: "(method) Foo.__bar(): number", ranges: [r1] }
16-
]);
10+
verify.singleReferenceGroup("(method) Foo.__bar(): number");

0 commit comments

Comments
 (0)