Skip to content

Commit c05fac7

Browse files
Use an element access when displaying literal members.
1 parent 5814261 commit c05fac7

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

src/compiler/checker.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,12 +1808,38 @@ namespace ts {
18081808

18091809
/**
18101810
* Writes only the name of the symbol out to the writer. Uses the original source text
1811-
* for the name of the symbol if it is available to match how the user inputted the name.
1811+
* for the name of the symbol if it is available to match how the user wrote the name.
18121812
*/
18131813
function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void {
18141814
writer.writeSymbol(getNameOfSymbol(symbol), symbol);
18151815
}
18161816

1817+
/**
1818+
* Writes a property access or element access with the name of the symbol out to the writer.
1819+
* Uses the original source text for the name of the symbol if it is available to match how the user wrote the name,
1820+
* ensuring that any names written with literals use element accesses.
1821+
*/
1822+
function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
1823+
const symbolName = getNameOfSymbol(symbol);
1824+
const firstChar = symbolName.charCodeAt(0);
1825+
const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
1826+
1827+
if (needsElementAccess) {
1828+
writePunctuation(writer, SyntaxKind.OpenBracketToken);
1829+
if (isSingleOrDoubleQuote(firstChar)) {
1830+
writer.writeStringLiteral(symbolName);
1831+
}
1832+
else {
1833+
writer.writeSymbol(symbolName, symbol);
1834+
}
1835+
writePunctuation(writer, SyntaxKind.CloseBracketToken);
1836+
}
1837+
else {
1838+
writePunctuation(writer, SyntaxKind.DotToken);
1839+
writer.writeSymbol(symbolName, symbol);
1840+
}
1841+
}
1842+
18171843
/**
18181844
* Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
18191845
* Meaning needs to be specified if the enclosing declaration is given
@@ -1832,10 +1858,12 @@ namespace ts {
18321858
buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
18331859
}
18341860
}
1835-
writePunctuation(writer, SyntaxKind.DotToken);
1861+
appendPropertyOrElementAccessForSymbol(symbol, writer);
1862+
}
1863+
else {
1864+
appendSymbolNameOnly(symbol, writer);
18361865
}
18371866
parentSymbol = symbol;
1838-
appendSymbolNameOnly(symbol, writer);
18391867
}
18401868

18411869
// const the writer know we just wrote out a symbol. The declaration emitter writer uses
@@ -2030,10 +2058,10 @@ namespace ts {
20302058
if (symbol) {
20312059
// Always use 'typeof T' for type of class, enum, and module objects
20322060
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
2033-
writeTypeofSymbol(type, flags);
2061+
writeTypeOSymbol(type, flags);
20342062
}
20352063
else if (shouldWriteTypeOfFunctionSymbol()) {
2036-
writeTypeofSymbol(type, flags);
2064+
writeTypeOSymbol(type, flags);
20372065
}
20382066
else if (contains(symbolStack, symbol)) {
20392067
// If type is an anonymous type literal in a type alias declaration, use type alias name
@@ -2078,7 +2106,7 @@ namespace ts {
20782106
}
20792107
}
20802108

2081-
function writeTypeofSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
2109+
function writeTypeOSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
20822110
writeKeyword(writer, SyntaxKind.TypeOfKeyword);
20832111
writeSpace(writer);
20842112
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,10 @@ namespace ts {
11961196
return isRequire && (!checkArgumentIsStringLiteral || (<CallExpression>expression).arguments[0].kind === SyntaxKind.StringLiteral);
11971197
}
11981198

1199+
export function isSingleOrDoubleQuote(charCode: number) {
1200+
return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote;
1201+
}
1202+
11991203
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
12001204
/// assignments we treat as special in the binder
12011205
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {

0 commit comments

Comments
 (0)