mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-24 12:19:20 +00:00
Fix bug for generating snippet if the object type contained a method signature
This commit is contained in:
@@ -632,7 +632,6 @@ export function snippetForFunctionCall(
|
||||
let hasAddedParameters = false;
|
||||
|
||||
const snippet = new vscode.SnippetString();
|
||||
const methodName = displayParts.find(part => part.kind === 'methodName');
|
||||
if (item.insertText) {
|
||||
if (typeof item.insertText === 'string') {
|
||||
snippet.appendText(item.insertText);
|
||||
@@ -640,17 +639,18 @@ export function snippetForFunctionCall(
|
||||
return item.insertText;
|
||||
}
|
||||
} else {
|
||||
snippet.appendText((methodName && methodName.text) || item.label);
|
||||
snippet.appendText(item.label);
|
||||
}
|
||||
snippet.appendText('(');
|
||||
|
||||
const functionSignatureDisplayParts = getFunctionSignatureDisplayParts(displayParts, item.label);
|
||||
let parenCount = 0;
|
||||
let i = 0;
|
||||
for (; i < displayParts.length; ++i) {
|
||||
const part = displayParts[i];
|
||||
for (; i < functionSignatureDisplayParts.length; ++i) {
|
||||
const part = functionSignatureDisplayParts[i];
|
||||
// Only take top level paren names
|
||||
if (part.kind === 'parameterName' && parenCount === 1) {
|
||||
const next = displayParts[i + 1];
|
||||
const next = functionSignatureDisplayParts[i + 1];
|
||||
// Skip optional parameters
|
||||
const nameIsFollowedByOptionalIndicator = next && next.text === '?';
|
||||
if (!nameIsFollowedByOptionalIndicator) {
|
||||
@@ -684,6 +684,43 @@ export function snippetForFunctionCall(
|
||||
return snippet;
|
||||
}
|
||||
|
||||
function getFunctionSignatureDisplayParts(
|
||||
displayParts: ReadonlyArray<Proto.SymbolDisplayPart>,
|
||||
label: string,
|
||||
): ReadonlyArray<Proto.SymbolDisplayPart> {
|
||||
let start: number | undefined;
|
||||
let end: number | undefined;
|
||||
|
||||
let index = 0;
|
||||
let nestingLevel = 0;
|
||||
for (; index < displayParts.length; ++index) {
|
||||
const part = displayParts[index];
|
||||
if (part.kind === 'methodName' || part.kind === 'functionName' || part.kind === 'text' && part.text === label) {
|
||||
if (nestingLevel === 0) {
|
||||
start = index;
|
||||
}
|
||||
} else if (part.kind === 'punctuation') {
|
||||
switch (part.text) {
|
||||
case '(':
|
||||
++nestingLevel;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
--nestingLevel;
|
||||
if (nestingLevel <= 0) {
|
||||
end = index;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof start === 'number' && typeof end === 'number') {
|
||||
return displayParts.slice(start, end);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function shouldExcludeCompletionEntry(
|
||||
element: Proto.CompletionEntry,
|
||||
completionConfiguration: CompletionConfiguration
|
||||
|
||||
@@ -81,7 +81,7 @@ suite('typescript function call snippets', () => {
|
||||
'foo(${1:a}, ${2:b})$0');
|
||||
});
|
||||
|
||||
test('Should skip over return type', async () => {
|
||||
test('Should skip over return type while extracting parameters', async () => {
|
||||
assert.strictEqual(
|
||||
snippetForFunctionCall(
|
||||
{ label: 'foo' },
|
||||
@@ -89,4 +89,13 @@ suite('typescript function call snippets', () => {
|
||||
).value,
|
||||
'foo(${1:a})$0');
|
||||
});
|
||||
|
||||
test('Should skip over prefix type while extracting parameters', async () => {
|
||||
assert.strictEqual(
|
||||
snippetForFunctionCall(
|
||||
{ label: 'foo' },
|
||||
[{ "text": "(", "kind": "punctuation" }, { "text": "method", "kind": "text" }, { "text": ")", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "Array", "kind": "localName" }, { "text": "<", "kind": "punctuation" }, { "text": "{", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "dispose", "kind": "methodName" }, { "text": "(", "kind": "punctuation" }, { "text": ")", "kind": "punctuation" }, { "text": ":", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "any", "kind": "keyword" }, { "text": ";", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "}", "kind": "punctuation" }, { "text": ">", "kind": "punctuation" }, { "text": ".", "kind": "punctuation" }, { "text": "foo", "kind": "methodName" }, { "text": "(", "kind": "punctuation" }, { "text": "searchElement", "kind": "parameterName" }, { "text": ":", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "{", "kind": "punctuation" }, { "text": "\n", "kind": "lineBreak" }, { "text": " ", "kind": "space" }, { "text": "dispose", "kind": "methodName" }, { "text": "(", "kind": "punctuation" }, { "text": ")", "kind": "punctuation" }, { "text": ":", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "any", "kind": "keyword" }, { "text": ";", "kind": "punctuation" }, { "text": "\n", "kind": "lineBreak" }, { "text": "}", "kind": "punctuation" }, { "text": ",", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "fromIndex", "kind": "parameterName" }, { "text": "?", "kind": "punctuation" }, { "text": ":", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "number", "kind": "keyword" }, { "text": ")", "kind": "punctuation" }, { "text": ":", "kind": "punctuation" }, { "text": " ", "kind": "space" }, { "text": "number", "kind": "keyword" }]
|
||||
).value,
|
||||
'foo(${1:searchElement}$2)$0');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user