Skip to content

Commit b8d575a

Browse files
Preserve symbol name string delimiters
1 parent 638ceea commit b8d575a

File tree

71 files changed

+263
-240
lines changed

Some content is hidden

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

71 files changed

+263
-240
lines changed

src/compiler/checker.ts

+30-12
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
17101710
return typeToStringWorker(type, getParseTreeNode(enclosingDeclaration), flags);
17111711
},
17121712
symbolToString: (symbol, enclosingDeclaration, meaning, flags) => {
1713-
return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags);
1713+
return symbolToStringWorker(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags);
17141714
},
17151715
typePredicateToString: (predicate, enclosingDeclaration, flags) => {
17161716
return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags);
@@ -1722,7 +1722,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
17221722
return typeToStringWorker(type, getParseTreeNode(enclosingDeclaration), flags, writer, verbosityLevel, out);
17231723
},
17241724
writeSymbol: (symbol, enclosingDeclaration, meaning, flags, writer) => {
1725-
return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
1725+
return symbolToStringWorker(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
17261726
},
17271727
writeTypePredicate: (predicate, enclosingDeclaration, flags, writer) => {
17281728
return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags, writer);
@@ -5988,8 +5988,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
59885988
}
59895989

59905990
function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string {
5991-
let nodeFlags = NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseDoubleQuotesForStringLiteralType;
5991+
return symbolToStringWorker(symbol, enclosingDeclaration, meaning, flags | SymbolFormatFlags.UseDoubleQuotesForStringLiteralType, writer);
5992+
}
5993+
function symbolToStringWorker(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string {
5994+
let nodeFlags = NodeBuilderFlags.IgnoreErrors;
59925995
let internalNodeFlags = InternalNodeBuilderFlags.None;
5996+
if (flags & SymbolFormatFlags.UseSingleQuotesForStringLiteralType) {
5997+
nodeFlags |= NodeBuilderFlags.UseSingleQuotesForStringLiteralType;
5998+
}
5999+
if (flags & SymbolFormatFlags.UseDoubleQuotesForStringLiteralType) {
6000+
nodeFlags |= NodeBuilderFlags.UseDoubleQuotesForStringLiteralType;
6001+
}
59936002
if (flags & SymbolFormatFlags.UseOnlyExternalAliasing) {
59946003
nodeFlags |= NodeBuilderFlags.UseOnlyExternalAliasing;
59956004
}
@@ -6330,9 +6339,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
63306339
const node = range as Node as StringLiteral;
63316340
return setOriginalNode(
63326341
context.flags & (NodeBuilderFlags.UseSingleQuotesForStringLiteralType | NodeBuilderFlags.UseDoubleQuotesForStringLiteralType) ?
6333-
factory.createStringLiteral(node.text, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)):
6334-
factory.createStringLiteralFromNode(node),
6335-
node
6342+
factory.createStringLiteral(node.text, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)) :
6343+
factory.createStringLiteralFromNode(node),
6344+
node,
63366345
) as Node as T;
63376346
}
63386347
else {
@@ -8543,10 +8552,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
85438552
}
85448553
let firstChar = symbolName.charCodeAt(0);
85458554

8555+
let useSingleQuote = !(context.flags & NodeBuilderFlags.UseDoubleQuotesForStringLiteralType) &&
8556+
(!!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType) || firstChar === CharacterCodes.singleQuote);
8557+
85468558
if (isSingleOrDoubleQuote(firstChar) && some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
8547-
return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context));
8559+
return factory.createStringLiteral(getSpecifierForModuleSymbol(symbol, context), useSingleQuote);
85488560
}
8549-
if (index === 0 || canUsePropertyAccess(symbolName, languageVersion)) {
8561+
if (canUsePropertyAccess(symbolName, languageVersion) || (index === 0 && firstChar === CharacterCodes.openBracket)) {
85508562
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
85518563
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
85528564
identifier.symbol = symbol;
@@ -8557,21 +8569,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
85578569
if (firstChar === CharacterCodes.openBracket) {
85588570
symbolName = symbolName.substring(1, symbolName.length - 1);
85598571
firstChar = symbolName.charCodeAt(0);
8572+
useSingleQuote = !(context.flags & NodeBuilderFlags.UseDoubleQuotesForStringLiteralType) &&
8573+
(!!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType) || firstChar === CharacterCodes.singleQuote);
85608574
}
85618575
let expression: Expression | undefined;
85628576
if (isSingleOrDoubleQuote(firstChar) && !(symbol.flags & SymbolFlags.EnumMember)) {
8563-
expression = factory.createStringLiteral(stripQuotes(symbolName).replace(/\\./g, s => s.substring(1)), firstChar === CharacterCodes.singleQuote);
8577+
const stringLiteralName = factory.createStringLiteral(stripQuotes(symbolName).replace(/\\./g, s => s.substring(1)), useSingleQuote);
8578+
stringLiteralName.symbol = symbol;
8579+
expression = stringLiteralName;
85648580
}
85658581
else if (("" + +symbolName) === symbolName) {
8566-
expression = factory.createNumericLiteral(+symbolName);
8582+
const numberLiteralName = factory.createNumericLiteral(+symbolName);
8583+
numberLiteralName.symbol = symbol;
8584+
expression = numberLiteralName;
85678585
}
85688586
if (!expression) {
85698587
const identifier = setEmitFlags(factory.createIdentifier(symbolName), EmitFlags.NoAsciiEscaping);
85708588
if (typeParameterNodes) setIdentifierTypeArguments(identifier, factory.createNodeArray<TypeNode | TypeParameterDeclaration>(typeParameterNodes));
85718589
identifier.symbol = symbol;
85728590
expression = identifier;
85738591
}
8574-
return factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression);
8592+
return index === 0 ? expression : factory.createElementAccessExpression(createExpressionFromSymbolChain(chain, index - 1), expression);
85758593
}
85768594
}
85778595
}
@@ -8599,7 +8617,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
85998617

86008618
function getPropertyNameNodeForSymbol(symbol: Symbol, context: NodeBuilderContext) {
86018619
const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed);
8602-
const singleQuote = context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType ? true:
8620+
const singleQuote = context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType ? true :
86038621
context.flags & NodeBuilderFlags.UseDoubleQuotesForStringLiteralType ? false :
86048622
!!length(symbol.declarations) && every(symbol.declarations, isSingleQuotedStringNamed);
86058623
const isMethod = !!(symbol.flags & SymbolFlags.Method);

src/compiler/emitter.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
20992099
// SyntaxKind.TemplateTail
21002100
function emitLiteral(node: LiteralLikeNode, jsxAttributeEscape: boolean) {
21012101
const text = getLiteralTextOfNode(node, /*sourceFile*/ undefined, printerOptions.neverAsciiEscape, jsxAttributeEscape);
2102-
if (
2102+
if ((node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) && (node as StringLiteral).symbol) {
2103+
writeSymbol(text, (node as StringLiteral).symbol);
2104+
}
2105+
else if (
21032106
(printerOptions.sourceMap || printerOptions.inlineSourceMap)
21042107
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))
21052108
) {

src/compiler/expressionToTypeNode.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,9 @@ export function createSyntacticTypeNodeBuilder(
534534
if (isStringLiteral(node)) {
535535
return setOriginalNode(
536536
context.flags & (NodeBuilderFlags.UseSingleQuotesForStringLiteralType | NodeBuilderFlags.UseDoubleQuotesForStringLiteralType) ?
537-
factory.createStringLiteral(node.text, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)):
538-
factory.createStringLiteralFromNode(node),
539-
node
537+
factory.createStringLiteral(node.text, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)) :
538+
factory.createStringLiteralFromNode(node),
539+
node,
540540
);
541541
}
542542
if (isConditionalTypeNode(node)) {

src/compiler/types.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -5545,7 +5545,7 @@ export const enum TypeFormatFlags {
55455545

55465546
UseAliasDefinedOutsideCurrentScope = 1 << 14, // For a `type T = ... ` defined in a different file, write `T` instead of its value, even though `T` can't be accessed in the current scope.
55475547
UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type
5548-
UseDoubleQuotesForStringLiteralType = 1 << 30, // Preserve source quote types for string literal type
5548+
UseDoubleQuotesForStringLiteralType = 1 << 30, // Use double quotes for string literal type
55495549
NoTypeReduction = 1 << 29, // Don't call getReducedType
55505550
OmitThisParameter = 1 << 25,
55515551

@@ -5594,6 +5594,9 @@ export const enum SymbolFormatFlags {
55945594

55955595
// Skip building an accessible symbol chain
55965596
/** @internal */ DoNotIncludeSymbolChain = 1 << 5,
5597+
5598+
UseSingleQuotesForStringLiteralType = 1 << 6, // Use single quotes for string literal type
5599+
UseDoubleQuotesForStringLiteralType = 1 << 7, // Use double quote for string literal type
55975600
}
55985601

55995602
/** @internal */

tests/baselines/reference/aliasDoesNotDuplicateSignatures.symbols

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ declare namespace demoNS {
88
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
99
}
1010
declare module 'demoModule' {
11-
>'demoModule' : Symbol("demoModule", Decl(demo.d.ts, 2, 1))
11+
>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1))
1212

1313
import alias = demoNS;
1414
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))

tests/baselines/reference/ambientDeclarations.symbols

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var q = M1.fn();
162162
// Ambient external module in the global module
163163
// Ambient external module with a string literal name that is a top level external module name
164164
declare module 'external1' {
165-
>'external1' : Symbol("external1", Decl(ambientDeclarations.ts, 67, 16))
165+
>'external1' : Symbol('external1', Decl(ambientDeclarations.ts, 67, 16))
166166

167167
var q;
168168
>q : Symbol(q, Decl(ambientDeclarations.ts, 72, 7))

tests/baselines/reference/ambientDeclarationsExternal.symbols

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var n: number;
2222
=== decls.ts ===
2323
// Ambient external module with export assignment
2424
declare module 'equ' {
25-
>'equ' : Symbol("equ", Decl(decls.ts, 0, 0))
25+
>'equ' : Symbol('equ', Decl(decls.ts, 0, 0))
2626

2727
var x;
2828
>x : Symbol(x, Decl(decls.ts, 2, 7))
@@ -32,7 +32,7 @@ declare module 'equ' {
3232
}
3333

3434
declare module 'equ2' {
35-
>'equ2' : Symbol("equ2", Decl(decls.ts, 4, 1))
35+
>'equ2' : Symbol('equ2', Decl(decls.ts, 4, 1))
3636

3737
var x: number;
3838
>x : Symbol(x, Decl(decls.ts, 7, 7))

tests/baselines/reference/ambientErrors.symbols

+3-3
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ module M2 {
9292
>M2 : Symbol(M2, Decl(ambientErrors.ts, 42, 1))
9393

9494
declare module 'nope' { }
95-
>'nope' : Symbol("nope", Decl(ambientErrors.ts, 45, 11))
95+
>'nope' : Symbol('nope', Decl(ambientErrors.ts, 45, 11))
9696
}
9797

9898
// Ambient external module with a string literal name that isn't a top level external module name
9999
declare module '../foo' { }
100-
>'../foo' : Symbol("../foo", Decl(ambientErrors.ts, 47, 1))
100+
>'../foo' : Symbol('../foo', Decl(ambientErrors.ts, 47, 1))
101101

102102
// Ambient external module with export assignment and other exported members
103103
declare module 'bar' {
104-
>'bar' : Symbol("bar", Decl(ambientErrors.ts, 50, 27))
104+
>'bar' : Symbol('bar', Decl(ambientErrors.ts, 50, 27))
105105

106106
var n;
107107
>n : Symbol(n, Decl(ambientErrors.ts, 54, 7))

tests/baselines/reference/ambientExternalModuleWithInternalImportDeclaration.symbols

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var c = new A();
1111

1212
=== ambientExternalModuleWithInternalImportDeclaration_0.ts ===
1313
declare module 'M' {
14-
>'M' : Symbol("M", Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 0))
14+
>'M' : Symbol('M', Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 0))
1515

1616
module C {
1717
>C : Symbol(C, Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 0, 20), Decl(ambientExternalModuleWithInternalImportDeclaration_0.ts, 3, 5))

tests/baselines/reference/ambientExternalModuleWithoutInternalImportDeclaration.symbols

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var c = new A();
1111

1212
=== ambientExternalModuleWithoutInternalImportDeclaration_0.ts ===
1313
declare module 'M' {
14-
>'M' : Symbol("M", Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 0))
14+
>'M' : Symbol('M', Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 0))
1515

1616
module C {
1717
>C : Symbol(C, Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 0, 20), Decl(ambientExternalModuleWithoutInternalImportDeclaration_0.ts, 3, 5))

tests/baselines/reference/api/typescript.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6414,6 +6414,8 @@ declare namespace ts {
64146414
UseOnlyExternalAliasing = 2,
64156415
AllowAnyNodeKind = 4,
64166416
UseAliasDefinedOutsideCurrentScope = 8,
6417+
UseSingleQuotesForStringLiteralType = 64,
6418+
UseDoubleQuotesForStringLiteralType = 128,
64176419
}
64186420
enum TypePredicateKind {
64196421
This = 0,

0 commit comments

Comments
 (0)