Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df8cb9d

Browse filesBrowse files
author
Andy
authored
Merge pull request microsoft#13364 from Microsoft/string_literal_completions_fix
String literal completions: Use call signature only if we are *immediately* in a call expression
2 parents 1040247 + 23fa422 commit df8cb9d
Copy full SHA for df8cb9d

5 files changed

+37-27Lines changed: 37 additions & 27 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/moduleNameResolver.ts‎

Copy file name to clipboardExpand all lines: src/compiler/moduleNameResolver.ts
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace ts {
1515
}
1616

1717
/** Array that is only intended to be pushed to, never read. */
18-
interface Push<T> {
18+
export interface Push<T> {
1919
push(value: T): void;
2020
}
2121

@@ -357,7 +357,7 @@ namespace ts {
357357
* Then it computes the set of parent folders for 'directory' that should have the same module resolution result
358358
* and for every parent folder in set it adds entry: parent -> module resolution. .
359359
* Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
360-
* Set of parent folders that should have the same result will be:
360+
* Set of parent folders that should have the same result will be:
361361
* [
362362
* /a/b/c/d, /a/b/c, /a/b
363363
* ]
@@ -391,7 +391,7 @@ namespace ts {
391391
}
392392
}
393393
}
394-
394+
395395
function getCommonPrefix(directory: Path, resolution: string) {
396396
if (resolution === undefined) {
397397
return undefined;
@@ -1022,15 +1022,15 @@ namespace ts {
10221022

10231023
/**
10241024
* Represents result of search. Normally when searching among several alternatives we treat value `undefined` as indicator
1025-
* that search fails and we should try another option.
1025+
* that search fails and we should try another option.
10261026
* However this does not allow us to represent final result that should be used instead of further searching (i.e. a final result that was found in cache).
10271027
* SearchResult is used to deal with this issue, its values represents following outcomes:
10281028
* - undefined - not found, continue searching
10291029
* - { value: undefined } - not found - stop searching
10301030
* - { value: <some-value> } - found - stop searching
10311031
*/
10321032
type SearchResult<T> = { value: T | undefined } | undefined;
1033-
1033+
10341034
/**
10351035
* Wraps value to SearchResult.
10361036
* @returns undefined if value is undefined or { value } otherwise
Collapse file

‎src/services/completions.ts‎

Copy file name to clipboardExpand all lines: src/services/completions.ts
+18-20Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
/// <reference path='../compiler/utilities.ts' />
2-
31
/* @internal */
42
namespace ts.Completions {
5-
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo {
3+
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined {
64
if (isInReferenceComment(sourceFile, position)) {
75
return getTripleSlashReferenceCompletion(sourceFile, position);
86
}
@@ -134,7 +132,7 @@ namespace ts.Completions {
134132
return uniqueNames;
135133
}
136134

137-
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number) {
135+
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number): CompletionInfo | undefined {
138136
const node = findPrecedingToken(position, sourceFile);
139137
if (!node || node.kind !== SyntaxKind.StringLiteral) {
140138
return undefined;
@@ -174,7 +172,7 @@ namespace ts.Completions {
174172
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node);
175173
}
176174
else {
177-
const argumentInfo = SignatureHelp.getContainingArgumentInfo(node, position, sourceFile);
175+
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
178176
if (argumentInfo) {
179177
// Get string literal completions from specialized signatures of the target
180178
// i.e. declare function f(a: 'A');
@@ -188,7 +186,7 @@ namespace ts.Completions {
188186
}
189187
}
190188

191-
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement) {
189+
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement): CompletionInfo | undefined {
192190
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
193191
const entries: CompletionEntry[] = [];
194192
if (type) {
@@ -199,7 +197,7 @@ namespace ts.Completions {
199197
}
200198
}
201199

202-
function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo) {
200+
function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo): CompletionInfo | undefined {
203201
const candidates: Signature[] = [];
204202
const entries: CompletionEntry[] = [];
205203

@@ -219,7 +217,7 @@ namespace ts.Completions {
219217
return undefined;
220218
}
221219

222-
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression) {
220+
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression): CompletionInfo | undefined {
223221
const type = typeChecker.getTypeAtLocation(node.expression);
224222
const entries: CompletionEntry[] = [];
225223
if (type) {
@@ -231,7 +229,7 @@ namespace ts.Completions {
231229
return undefined;
232230
}
233231

234-
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral) {
232+
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral): CompletionInfo | undefined {
235233
const type = typeChecker.getContextualType(node);
236234
if (type) {
237235
const entries: CompletionEntry[] = [];
@@ -243,26 +241,26 @@ namespace ts.Completions {
243241
return undefined;
244242
}
245243

246-
function addStringLiteralCompletionsFromType(type: Type, result: CompletionEntry[]): void {
244+
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>): void {
247245
if (type && type.flags & TypeFlags.TypeParameter) {
248246
type = typeChecker.getApparentType(type);
249247
}
250248
if (!type) {
251249
return;
252250
}
253251
if (type.flags & TypeFlags.Union) {
254-
forEach((<UnionType>type).types, t => addStringLiteralCompletionsFromType(t, result));
255-
}
256-
else {
257-
if (type.flags & TypeFlags.StringLiteral) {
258-
result.push({
259-
name: (<LiteralType>type).text,
260-
kindModifiers: ScriptElementKindModifier.none,
261-
kind: ScriptElementKind.variableElement,
262-
sortText: "0"
263-
});
252+
for (const t of (<UnionType>type).types) {
253+
addStringLiteralCompletionsFromType(t, result);
264254
}
265255
}
256+
else if (type.flags & TypeFlags.StringLiteral) {
257+
result.push({
258+
name: (<LiteralType>type).text,
259+
kindModifiers: ScriptElementKindModifier.none,
260+
kind: ScriptElementKind.variableElement,
261+
sortText: "0"
262+
});
263+
}
266264
}
267265

268266
function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral): CompletionInfo {
Collapse file

‎src/services/signatureHelp.ts‎

Copy file name to clipboardExpand all lines: src/services/signatureHelp.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ namespace ts.SignatureHelp {
260260
* Returns relevant information for the argument list and the current argument if we are
261261
* in the argument of an invocation; returns undefined otherwise.
262262
*/
263-
function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo {
263+
export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo {
264264
if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) {
265265
const callExpression = <CallExpression>node.parent;
266266
// There are 3 cases to handle:
Collapse file
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////interface Foo {
4+
//// x: "abc" | "def";
5+
////}
6+
////function bar(f: Foo) { };
7+
////bar({x: "/**/"});
8+
9+
goTo.marker();
10+
verify.completionListContains("abc");
11+
verify.completionListContains("def");
12+
verify.completionListCount(2);
Collapse file

‎tests/webTestServer.ts‎

Copy file name to clipboardExpand all lines: tests/webTestServer.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function dir(dirPath: string, spec?: string, options?: any) {
129129
function deleteFolderRecursive(dirPath: string) {
130130
if (fs.existsSync(dirPath)) {
131131
fs.readdirSync(dirPath).forEach((file) => {
132-
const curPath = path.join(path, file);
132+
const curPath = path.join(dirPath, file);
133133
if (fs.statSync(curPath).isDirectory()) { // recurse
134134
deleteFolderRecursive(curPath);
135135
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.