From 56accb08a1e4ff63b9ccdd5217b895493e997870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 22 Sep 2023 00:05:34 +0200 Subject: [PATCH] Fixed string completions that require escaping (#55118) --- src/services/stringCompletions.ts | 9 ++++++- .../fourslash/stringCompletionsVsEscaping.ts | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/stringCompletionsVsEscaping.ts diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index be13f979f5c..c19aaf541be 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -32,6 +32,7 @@ import { endsWith, ensureTrailingDirectorySeparator, equateStringsCaseSensitive, + escapeString, Extension, fileExtensionIsOneOf, filter, @@ -63,6 +64,7 @@ import { getSupportedExtensions, getSupportedExtensionsWithJsonIfResolveJsonModule, getTextOfJsxAttributeName, + getTextOfNode, getTokenAtPosition, hasIndexSignature, hasProperty, @@ -262,8 +264,13 @@ function convertStringLiteralCompletions( return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, optionalReplacementSpan, entries }; } case StringLiteralCompletionKind.Types: { + const quoteChar = contextToken.kind === SyntaxKind.NoSubstitutionTemplateLiteral + ? CharacterCodes.backtick + : startsWith(getTextOfNode(contextToken), "'") + ? CharacterCodes.singleQuote + : CharacterCodes.doubleQuote; const entries = completion.types.map(type => ({ - name: type.value, + name: escapeString(type.value, quoteChar), kindModifiers: ScriptElementKindModifier.none, kind: ScriptElementKind.string, sortText: SortText.LocationPriority, diff --git a/tests/cases/fourslash/stringCompletionsVsEscaping.ts b/tests/cases/fourslash/stringCompletionsVsEscaping.ts new file mode 100644 index 00000000000..816051e56a5 --- /dev/null +++ b/tests/cases/fourslash/stringCompletionsVsEscaping.ts @@ -0,0 +1,24 @@ +/// + +//// type Value

= `var(--\\\\, ${P})` +//// export const value: Value<'one' | 'two'> = "/*1*/" +//// +//// export const test: `\ntest\n` = '/*2*/' +//// +//// export const doubleQuoted1: `"double-quoted"` = '/*3*/' +//// export const doubleQuoted2: `"double-quoted"` = "/*4*/" +//// +//// export const singleQuoted2: `'single-quoted'` = "/*5*/" +//// export const singleQuoted2: `'single-quoted'` = '/*6*/' +//// +//// export const backtickQuoted1: '`backtick-quoted`' = "/*7*/" +//// export const backtickQuoted2: '`backtick-quoted`' = `/*8*/` + +verify.completions({ marker: "1", exact: ["var(--\\\\\\\\, one)", "var(--\\\\\\\\, two)"] }); +verify.completions({ marker: "2", exact: ["\\ntest\\n"] }); +verify.completions({ marker: "3", exact: ['"double-quoted"'] }); +verify.completions({ marker: "4", exact: ['\\\"double-quoted\\\"'] }); +verify.completions({ marker: "5", exact: ["'single-quoted'"] }); +verify.completions({ marker: "6", exact: ["\\'single-quoted\\'"] }); +verify.completions({ marker: "7", exact: ["`backtick-quoted`"] }); +verify.completions({ marker: "8", exact: ["\\`backtick-quoted\\`"] });