From ea6a19233edd4804108b9a9afc9c0c34618fbbbc Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 6 Feb 2018 08:14:06 -0800 Subject: [PATCH] Escape quotes in bracketed completions --- src/services/completions.ts | 9 ++++++--- .../completionListInvalidMemberNames_escapeQuote.ts | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionListInvalidMemberNames_escapeQuote.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 6f4cadec7e19d..efb9124734cde 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -180,11 +180,10 @@ namespace ts.Completions { let replacementSpan: TextSpan | undefined; if (includeInsertTextCompletions) { if (origin && origin.type === "this-type") { - insertText = needsConvertPropertyAccess ? `this["${name}"]` : `this.${name}`; + insertText = needsConvertPropertyAccess ? `this[${quote(name)}]` : `this.${name}`; } else if (needsConvertPropertyAccess) { - // TODO: GH#20619 Use configured quote style - insertText = `["${name}"]`; + insertText = `[${quote(name)}]`; const dot = findChildOfKind(propertyAccessToConvert!, SyntaxKind.DotToken, sourceFile)!; // If the text after the '.' starts with this name, write over it. Else, add new text. const end = startsWith(name, propertyAccessToConvert!.name.text) ? propertyAccessToConvert!.name.end : dot.end; @@ -222,6 +221,10 @@ namespace ts.Completions { }; } + function quote(text: string): string { + // TODO: GH#20619 Use configured quote style + return JSON.stringify(text); + } function isRecommendedCompletionMatch(localSymbol: Symbol, recommendedCompletion: Symbol, checker: TypeChecker): boolean { return localSymbol === recommendedCompletion || diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_escapeQuote.ts b/tests/cases/fourslash/completionListInvalidMemberNames_escapeQuote.ts new file mode 100644 index 0000000000000..8d6dde442a1be --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames_escapeQuote.ts @@ -0,0 +1,7 @@ +/// + +////declare const x: { '"': 0 }; +////x[|./**/|]; + +const replacementSpan = test.ranges()[0]; +verify.completionsAt("", [{ name: '"', insertText: '["\\""]', replacementSpan }], { includeInsertTextCompletions: true });