Better template literals support in checker (#32064)

* Support template literals in enum declarations

* Support template literals in const enum access

* Support template literals in swith with typeof narrowing

* Support template literals in element access discriminant

* Support template literals in ambient module declaration

* Unify symbols for template literals in computed properties

* Unify expression position checks for template literals

* Support template literals in rename and find all references

* Mark computed properties with template literals as write access

* Inline startsWithQuote
This commit is contained in:
Andrii Dieiev
2019-09-27 22:04:13 +03:00
committed by Nathan Shively-Sanders
parent c0573c59c9
commit a34fdb203e
60 changed files with 2445 additions and 213 deletions

View File

@@ -2086,7 +2086,7 @@ namespace ts.Completions {
if (name === undefined
// If the symbol is external module, don't show it in the completion list
// (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
|| symbol.flags & SymbolFlags.Module && startsWithQuote(name)
|| symbol.flags & SymbolFlags.Module && isSingleOrDoubleQuote(name.charCodeAt(0))
// If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@"
|| isKnownSymbol(symbol)) {
return undefined;

View File

@@ -448,7 +448,7 @@ namespace ts.FindAllReferences {
function getTextSpan(node: Node, sourceFile: SourceFile, endNode?: Node): TextSpan {
let start = node.getStart(sourceFile);
let end = (endNode || node).getEnd();
if (node.kind === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(node)) {
Debug.assert(endNode === undefined);
start += 1;
end -= 1;
@@ -1234,8 +1234,9 @@ namespace ts.FindAllReferences.Core {
case SyntaxKind.Identifier:
return (node as Identifier).text.length === searchSymbolName.length;
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.StringLiteral: {
const str = node as StringLiteral;
const str = node as StringLiteralLike;
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(str) || isNameOfModuleDeclaration(node) || isExpressionOfExternalModuleImportEqualsDeclaration(node) || (isCallExpression(node.parent) && isBindableObjectDefinePropertyCall(node.parent) && node.parent.arguments[1] === node)) &&
str.text.length === searchSymbolName.length;
}

View File

@@ -81,7 +81,7 @@ namespace ts.Rename {
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
let start = node.getStart(sourceFile);
let width = node.getWidth(sourceFile);
if (node.kind === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(node)) {
// Exclude the quotes
start += 1;
width -= 2;
@@ -93,6 +93,7 @@ namespace ts.Rename {
switch (node.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.StringLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.ThisKeyword:
return true;
case SyntaxKind.NumericLiteral:

View File

@@ -2231,6 +2231,7 @@ namespace ts {
function getContainingObjectLiteralElementWorker(node: Node): ObjectLiteralElement | undefined {
switch (node.kind) {
case SyntaxKind.StringLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.NumericLiteral:
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;

View File

@@ -267,7 +267,7 @@ namespace ts {
isFunctionLike(node.parent) && (<FunctionLikeDeclaration>node.parent).name === node;
}
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral): boolean {
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral | NoSubstitutionTemplateLiteral): boolean {
switch (node.parent.kind) {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature: