Add 'name' property to Identifier (#17329)

* Add 'name' property to Identifier

* Rename to unescapedText

* Rename 'id.text' to 'id.escapedText'

* Rename 'id.unescapedText' to 'id.text'

* Make escapeIdentifier and unescapeIdentifier do nothing
This commit is contained in:
Andy
2017-07-25 13:16:34 -07:00
committed by GitHub
parent d4f8da0272
commit eadd084c82
84 changed files with 428 additions and 383 deletions

View File

@@ -557,7 +557,7 @@ namespace ts {
// Only bother calling into the typechecker if this is an identifier that
// could possibly resolve to a type name. This makes classification run
// in a third of the time it would normally take.
if (classifiableNames.has(identifier.text)) {
if (classifiableNames.has(identifier.escapedText)) {
const symbol = typeChecker.getSymbolAtLocation(node);
if (symbol) {
const type = classifySymbol(symbol, getMeaningFromLocation(node));

View File

@@ -1453,7 +1453,7 @@ namespace ts.Completions {
}
const name = element.propertyName || element.name;
existingImportsOrExports.set(name.text, true);
existingImportsOrExports.set(name.escapedText, true);
}
if (existingImportsOrExports.size === 0) {
@@ -1496,7 +1496,7 @@ namespace ts.Completions {
if (m.kind === SyntaxKind.BindingElement && (<BindingElement>m).propertyName) {
// include only identifiers in completion list
if ((<BindingElement>m).propertyName.kind === SyntaxKind.Identifier) {
existingName = (<Identifier>(<BindingElement>m).propertyName).text;
existingName = (<Identifier>(<BindingElement>m).propertyName).escapedText;
}
}
else {
@@ -1592,7 +1592,7 @@ namespace ts.Completions {
}
if (attr.kind === SyntaxKind.JsxAttribute) {
seenNames.set((<JsxAttribute>attr).name.text, true);
seenNames.set((<JsxAttribute>attr).name.escapedText, true);
}
}

View File

@@ -248,7 +248,7 @@ namespace ts.DocumentHighlights {
case SyntaxKind.ForOfStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.DoStatement:
if (!statement.label || isLabeledBy(node, unescapeLeadingUnderscores(statement.label.text))) {
if (!statement.label || isLabeledBy(node, statement.label.text)) {
return node;
}
break;
@@ -606,7 +606,7 @@ namespace ts.DocumentHighlights {
*/
function isLabeledBy(node: Node, labelName: string) {
for (let owner = node.parent; owner.kind === SyntaxKind.LabeledStatement; owner = owner.parent) {
if ((<LabeledStatement>owner).label.text === labelName) {
if ((<LabeledStatement>owner).label.escapedText === labelName) {
return true;
}
}

View File

@@ -122,7 +122,7 @@ namespace ts.FindAllReferences {
}
case "label": {
const { node } = def;
return { node, name: unescapeLeadingUnderscores(node.text), kind: ScriptElementKind.label, displayParts: [displayPart(unescapeLeadingUnderscores(node.text), SymbolDisplayPartKind.text)] };
return { node, name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] };
}
case "keyword": {
const { node } = def;
@@ -357,7 +357,7 @@ namespace ts.FindAllReferences.Core {
// Labels
if (isLabelName(node)) {
if (isJumpStatementTarget(node)) {
const labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), unescapeLeadingUnderscores((<Identifier>node).text));
const labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
// if we have a label definition, look within its statement for references, if not, then
// the label is undefined and we have no results..
return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition);
@@ -606,7 +606,7 @@ namespace ts.FindAllReferences.Core {
const bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
if (bindingElement) {
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, unescapeLeadingUnderscores((<Identifier>bindingElement.name).text));
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
}
return undefined;
}
@@ -718,7 +718,7 @@ namespace ts.FindAllReferences.Core {
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): SymbolAndEntries[] {
const references: Entry[] = [];
const sourceFile = container.getSourceFile();
const labelName = unescapeLeadingUnderscores(targetLabel.text);
const labelName = targetLabel.text;
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
for (const position of possiblePositions) {
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
@@ -735,7 +735,7 @@ namespace ts.FindAllReferences.Core {
// Compare the length so we filter out strict superstrings of the symbol we are looking for
switch (node && node.kind) {
case SyntaxKind.Identifier:
return unescapeLeadingUnderscores((node as Identifier).text).length === searchSymbolName.length;
return (node as Identifier).text.length === searchSymbolName.length;
case SyntaxKind.StringLiteral:
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&

View File

@@ -26,7 +26,7 @@ namespace ts.GoToDefinition {
// Labels
if (isJumpStatementTarget(node)) {
const labelName = unescapeLeadingUnderscores((<Identifier>node).text);
const labelName = (<Identifier>node).text;
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), labelName);
return label ? [createDefinitionInfoFromName(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
}

View File

@@ -238,7 +238,7 @@ namespace ts.FindAllReferences {
const { name } = importClause;
// If a default import has the same name as the default export, allow to rename it.
// Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that.
if (name && (!isForRename || name.text === symbolName(exportSymbol))) {
if (name && (!isForRename || name.escapedText === symbolName(exportSymbol))) {
const defaultImportAlias = checker.getSymbolAtLocation(name);
addSearch(name, defaultImportAlias);
}
@@ -258,7 +258,7 @@ namespace ts.FindAllReferences {
*/
function handleNamespaceImportLike(importName: Identifier): void {
// Don't rename an import that already has a different name than the export.
if (exportKind === ExportKind.ExportEquals && (!isForRename || importName.text === exportName)) {
if (exportKind === ExportKind.ExportEquals && (!isForRename || importName.escapedText === exportName)) {
addSearch(importName, checker.getSymbolAtLocation(importName));
}
}
@@ -267,7 +267,7 @@ namespace ts.FindAllReferences {
if (namedBindings) {
for (const element of namedBindings.elements) {
const { name, propertyName } = element;
if ((propertyName || name).text !== exportName) {
if ((propertyName || name).escapedText !== exportName) {
continue;
}
@@ -601,10 +601,10 @@ namespace ts.FindAllReferences {
return forEach(symbol.declarations, decl => {
if (isExportAssignment(decl)) {
return isIdentifier(decl.expression) ? decl.expression.text : undefined;
return isIdentifier(decl.expression) ? decl.expression.escapedText : undefined;
}
const name = getNameOfDeclaration(decl);
return name && name.kind === SyntaxKind.Identifier && name.text;
return name && name.kind === SyntaxKind.Identifier && name.escapedText;
});
}

View File

@@ -71,7 +71,7 @@ namespace ts.JsDoc {
forEachUnique(declarations, declaration => {
for (const tag of getJSDocTags(declaration)) {
if (tag.kind === SyntaxKind.JSDocTag) {
tags.push({ name: unescapeLeadingUnderscores(tag.tagName.text), text: tag.comment });
tags.push({ name: tag.tagName.text, text: tag.comment });
}
}
});
@@ -120,7 +120,7 @@ namespace ts.JsDoc {
}
export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] {
const nameThusFar = unescapeLeadingUnderscores(tag.name.text);
const nameThusFar = tag.name.text;
const jsdoc = tag.parent;
const fn = jsdoc.parent;
if (!ts.isFunctionLike(fn)) return [];
@@ -128,8 +128,8 @@ namespace ts.JsDoc {
return mapDefined(fn.parameters, param => {
if (!isIdentifier(param.name)) return undefined;
const name = unescapeLeadingUnderscores(param.name.text);
if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && t.name.text === name)
const name = param.name.text;
if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && t.name.escapedText === name)
|| nameThusFar !== undefined && !startsWith(name, nameThusFar)) {
return undefined;
}
@@ -213,7 +213,7 @@ namespace ts.JsDoc {
for (let i = 0; i < parameters.length; i++) {
const currentName = parameters[i].name;
const paramName = currentName.kind === SyntaxKind.Identifier ?
(<Identifier>currentName).text :
(<Identifier>currentName).escapedText :
"param" + i;
if (isJavaScriptFile) {
docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`;

View File

@@ -119,7 +119,7 @@ namespace ts.NavigateTo {
if (expression.kind === SyntaxKind.PropertyAccessExpression) {
const propertyAccess = <PropertyAccessExpression>expression;
if (includeLastPortion) {
containers.unshift(unescapeLeadingUnderscores(propertyAccess.name.text));
containers.unshift(propertyAccess.name.text);
}
return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true);
@@ -191,7 +191,7 @@ namespace ts.NavigateTo {
fileName: rawItem.fileName,
textSpan: createTextSpanFromNode(declaration),
// TODO(jfreeman): What should be the containerName when the container has a computed name?
containerName: containerName ? unescapeLeadingUnderscores((<Identifier>containerName).text) : "",
containerName: containerName ? (<Identifier>containerName).text : "",
containerKind: containerName ? getNodeKind(container) : ScriptElementKind.unknown
};
}

View File

@@ -442,7 +442,7 @@ namespace ts.NavigationBar {
function getJSDocTypedefTagName(node: JSDocTypedefTag): string {
if (node.name) {
return unescapeLeadingUnderscores(node.name.text);
return node.name.text;
}
else {
const parentNode = node.parent && node.parent.parent;
@@ -450,7 +450,7 @@ namespace ts.NavigationBar {
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
if (nameIdentifier.kind === SyntaxKind.Identifier) {
return unescapeLeadingUnderscores((<Identifier>nameIdentifier).text);
return nameIdentifier.text;
}
}
}

View File

@@ -239,7 +239,7 @@ namespace ts.Completions.PathCompletions {
const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined;
// Get modules that the type checker picked up
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(unescapeLeadingUnderscores(sym.name)));
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.getUnescapedName()));
let nonRelativeModuleNames = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string

View File

@@ -364,7 +364,7 @@ namespace ts {
class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
public kind: SyntaxKind.Identifier;
public text: __String;
public escapedText: __String;
_primaryExpressionBrand: any;
_memberExpressionBrand: any;
_leftHandSideExpressionBrand: any;
@@ -375,6 +375,10 @@ namespace ts {
constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) {
super(pos, end);
}
get text(): string {
return unescapeLeadingUnderscores(this.escapedText);
}
}
IdentifierObject.prototype.kind = SyntaxKind.Identifier;
@@ -601,7 +605,7 @@ namespace ts {
if (name.kind === SyntaxKind.ComputedPropertyName) {
const expr = (<ComputedPropertyName>name).expression;
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
return unescapeLeadingUnderscores((<PropertyAccessExpression>expr).name.text);
return (<PropertyAccessExpression>expr).name.text;
}
return getTextOfIdentifierOrLiteral(expr as (Identifier | LiteralExpression));
@@ -2065,7 +2069,7 @@ namespace ts {
function initializeNameTable(sourceFile: SourceFile): void {
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
sourceFile.forEachChild(function walk(node) {
if ((isIdentifier(node) || isStringOrNumericLiteral(node) && literalIsName(node)) && node.text) {
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteral(node) && literalIsName(node)) {
const text = getEscapedTextOfIdentifierOrLiteral(node);
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
}

View File

@@ -65,14 +65,14 @@ namespace ts.SignatureHelp {
? (<PropertyAccessExpression>expression).name
: undefined;
if (!name || !name.text) {
if (!name || !name.escapedText) {
return undefined;
}
const typeChecker = program.getTypeChecker();
for (const sourceFile of program.getSourceFiles()) {
const nameToDeclarations = sourceFile.getNamedDeclarations();
const declarations = nameToDeclarations.get(unescapeLeadingUnderscores(name.text));
const declarations = nameToDeclarations.get(name.text);
if (declarations) {
for (const declaration of declarations) {

View File

@@ -22,6 +22,10 @@ namespace ts {
forEachChild<T>(cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined;
}
export interface Identifier {
readonly text: string;
}
export interface Symbol {
getFlags(): SymbolFlags;
getName(): __String;

View File

@@ -203,7 +203,7 @@ namespace ts {
export function getTargetLabel(referenceNode: Node, labelName: string): Identifier {
while (referenceNode) {
if (referenceNode.kind === SyntaxKind.LabeledStatement && (<LabeledStatement>referenceNode).label.text === labelName) {
if (referenceNode.kind === SyntaxKind.LabeledStatement && (<LabeledStatement>referenceNode).label.escapedText === labelName) {
return (<LabeledStatement>referenceNode).label;
}
referenceNode = referenceNode.parent;