diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 70141c853ca..796c9603423 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -244,7 +244,7 @@ namespace ts { } Debug.assert(isWellKnownSymbolSyntactically(nameExpression)); - return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores((nameExpression).name.escapedText)); + return getPropertyNameForKnownSymbolName(idText((nameExpression).name)); } return getEscapedTextOfIdentifierOrLiteral(name); } @@ -1777,7 +1777,7 @@ namespace ts { // otherwise report generic error message. const span = getErrorSpanForNode(file, name); file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, - getStrictModeEvalOrArgumentsMessage(contextNode), unescapeLeadingUnderscores(identifier.escapedText))); + getStrictModeEvalOrArgumentsMessage(contextNode), idText(identifier))); } } } @@ -2431,7 +2431,7 @@ namespace ts { if (node.name) { node.name.parent = node; } - file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(prototypeSymbol.escapedName))); + file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, symbolName(prototypeSymbol))); } symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol); prototypeSymbol.parent = symbol; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff105ce9d1c..f6aeec2f704 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -227,8 +227,8 @@ namespace ts { getApparentType, isArrayLikeType, getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: (node, type) => unescapeLeadingUnderscores(getSuggestionForNonexistentProperty(node, type)), - getSuggestionForNonexistentSymbol: (location, name, meaning) => unescapeLeadingUnderscores(getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning)), + getSuggestionForNonexistentProperty: (node, type) => getSuggestionForNonexistentProperty(node, type), + getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), getBaseConstraintOfType, resolveName(name, location, meaning) { return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); @@ -1144,11 +1144,11 @@ namespace ts { !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { - let suggestion: __String | undefined; + let suggestion: string | undefined; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning); if (suggestion) { - error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), unescapeLeadingUnderscores(suggestion)); + error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestion); } } if (!suggestion) { @@ -2904,7 +2904,7 @@ namespace ts { parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : cloneBindingName(parameterDeclaration.name) : - unescapeLeadingUnderscores(parameterSymbol.escapedName); + symbolName(parameterSymbol); const questionToken = isOptionalParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : undefined; let parameterType = getTypeOfSymbol(parameterSymbol); @@ -3118,7 +3118,7 @@ namespace ts { return `"${escapeString(stringValue, CharacterCodes.doubleQuote)}"`; } } - return unescapeLeadingUnderscores(symbol.escapedName); + return symbolName(symbol); } function getSymbolDisplayBuilder(): SymbolDisplayBuilder { @@ -3577,7 +3577,7 @@ namespace ts { continue; } if (getDeclarationModifierFlagsFromSymbol(p) & (ModifierFlags.Private | ModifierFlags.Protected)) { - writer.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(p.escapedName)); + writer.reportPrivateInBaseOfClassExpression(symbolName(p)); } } const t = getTypeOfSymbol(p); @@ -7063,11 +7063,11 @@ namespace ts { } const type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & TypeFlags.Object)) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_be_a_class_or_interface_type, unescapeLeadingUnderscores(symbol.escapedName)); + error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbolName(symbol)); return arity ? emptyGenericType : emptyObjectType; } if (length((type).typeParameters) !== arity) { - error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, unescapeLeadingUnderscores(symbol.escapedName), arity); + error(getTypeDeclaration(symbol), Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity); return arity ? emptyGenericType : emptyObjectType; } return type; @@ -7580,7 +7580,7 @@ namespace ts { function getLiteralTypeFromPropertyName(prop: Symbol) { return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || startsWith(prop.escapedName as string, "__@") ? neverType : - getLiteralType(unescapeLeadingUnderscores(prop.escapedName)); + getLiteralType(symbolName(prop)); } function getLiteralTypeFromPropertyNames(type: Type) { @@ -7619,7 +7619,7 @@ namespace ts { const propName = indexType.flags & TypeFlags.StringOrNumberLiteral ? escapeLeadingUnderscores("" + (indexType).value) : accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ? - getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores(((accessExpression.argumentExpression).name).escapedText)) : + getPropertyNameForKnownSymbolName(idText(((accessExpression.argumentExpression).name))) : undefined; if (propName !== undefined) { const prop = getPropertyOfType(objectType, propName); @@ -8573,8 +8573,8 @@ namespace ts { if (!related) { if (reportErrors) { errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible, - unescapeLeadingUnderscores(sourceParams[i < sourceMax ? i : sourceMax].escapedName), - unescapeLeadingUnderscores(targetParams[i < targetMax ? i : targetMax].escapedName)); + symbolName(sourceParams[i < sourceMax ? i : sourceMax]), + symbolName(targetParams[i < targetMax ? i : targetMax])); } return Ternary.False; } @@ -8728,7 +8728,7 @@ namespace ts { const targetProperty = getPropertyOfType(targetEnumType, property.escapedName); if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) { if (errorReporter) { - errorReporter(Diagnostics.Property_0_is_missing_in_type_1, unescapeLeadingUnderscores(property.escapedName), + errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); } enumRelation.set(id, false); @@ -9077,7 +9077,7 @@ namespace ts { if (suggestion !== undefined) { reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, - symbolToString(prop), typeToString(target), unescapeLeadingUnderscores(suggestion)); + symbolToString(prop), typeToString(target), suggestion); } else { reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, @@ -10288,7 +10288,7 @@ namespace ts { const t = getTypeOfSymbol(p); if (t.flags & TypeFlags.ContainsWideningType) { if (!reportWideningErrorsInType(t)) { - error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, unescapeLeadingUnderscores(p.escapedName), typeToString(getWidenedType(t))); + error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t))); } errorReported = true; } @@ -10892,7 +10892,7 @@ namespace ts { } if (node.kind === SyntaxKind.PropertyAccessExpression) { const key = getFlowCacheKey((node).expression); - return key && key + "." + unescapeLeadingUnderscores((node).name.escapedText); + return key && key + "." + idText((node).name); } if (node.kind === SyntaxKind.BindingElement) { const container = (node as BindingElement).parent.parent; @@ -10909,7 +10909,7 @@ namespace ts { const name = element.propertyName || element.name; switch (name.kind) { case SyntaxKind.Identifier: - return unescapeLeadingUnderscores(name.escapedText); + return idText(name); case SyntaxKind.ComputedPropertyName: return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined; case SyntaxKind.StringLiteral: @@ -14005,7 +14005,7 @@ namespace ts { } // Wasn't found - error(node, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(node.tagName.escapedText), "JSX." + JsxNames.IntrinsicElements); + error(node, Diagnostics.Property_0_does_not_exist_on_type_1, idText(node.tagName), "JSX." + JsxNames.IntrinsicElements); return links.resolvedSymbol = unknownSymbol; } else { @@ -14260,8 +14260,8 @@ namespace ts { // Hello World const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); if (intrinsicElementsType !== unknownType) { - const stringLiteralTypeName = escapeLeadingUnderscores((elementType).value); - const intrinsicProp = getPropertyOfType(intrinsicElementsType, stringLiteralTypeName); + const stringLiteralTypeName = (elementType).value; + const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { return getTypeOfSymbol(intrinsicProp); } @@ -14269,7 +14269,7 @@ namespace ts { if (indexSignatureType) { return indexSignatureType; } - error(openingLikeElement, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(stringLiteralTypeName), "JSX." + JsxNames.IntrinsicElements); + error(openingLikeElement, Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements); } // If we need to report an error, we already done so here. So just return any to prevent any more error downstream return anyType; @@ -14563,7 +14563,7 @@ namespace ts { if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) { for (const attribute of openingLikeElement.attributes.properties) { if (isJsxAttribute(attribute) && !isKnownProperty(targetAttributesType, attribute.name.escapedText, /*isComparingJsxAttributes*/ true)) { - error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(attribute.name.escapedText), typeToString(targetAttributesType)); + error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, idText(attribute.name), typeToString(targetAttributesType)); // We break here so that errors won't be cascading break; } @@ -14762,7 +14762,7 @@ namespace ts { if (assignmentKind) { if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) { - error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, unescapeLeadingUnderscores(right.escapedText)); + error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, idText(right)); return unknownType; } } @@ -14788,13 +14788,13 @@ namespace ts { if (isInPropertyInitializer(node) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) && !isPropertyDeclaredInAncestorClass(prop)) { - error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, unescapeLeadingUnderscores(right.escapedText)); + error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, idText(right)); } else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration && node.parent.kind !== SyntaxKind.TypeReference && !isInAmbientContext(valueDeclaration) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) { - error(right, Diagnostics.Class_0_used_before_its_declaration, unescapeLeadingUnderscores(right.escapedText)); + error(right, Diagnostics.Class_0_used_before_its_declaration, idText(right)); } } @@ -14851,7 +14851,7 @@ namespace ts { } const suggestion = getSuggestionForNonexistentProperty(propNode, containingType); if (suggestion !== undefined) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), unescapeLeadingUnderscores(suggestion)); + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion); } else { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); @@ -14859,25 +14859,20 @@ namespace ts { diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo)); } - function getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): __String | undefined { - const suggestion = getSpellingSuggestionForName(unescapeLeadingUnderscores(node.escapedText), getPropertiesOfType(containingType), SymbolFlags.Value); - return suggestion && suggestion.escapedName; + function getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined { + const suggestion = getSpellingSuggestionForName(idText(node), getPropertiesOfType(containingType), SymbolFlags.Value); + return suggestion && symbolName(suggestion); } - function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): __String { + function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string { const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => { const symbol = getSymbol(symbols, name, meaning); - if (symbol) { - // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function - // So the table *contains* `x` but `x` isn't actually in scope. - // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. - return symbol; - } - return getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning); + // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function + // So the table *contains* `x` but `x` isn't actually in scope. + // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. + return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning); }); - if (result) { - return result.escapedName; - } + return result && symbolName(result); } /** @@ -14907,7 +14902,7 @@ namespace ts { } name = name.toLowerCase(); for (const candidate of symbols) { - let candidateName = unescapeLeadingUnderscores(candidate.escapedName); + let candidateName = symbolName(candidate); if (candidate.flags & meaning && candidateName && Math.abs(candidateName.length - name.length) < maximumLengthDifference) { @@ -15715,7 +15710,7 @@ namespace ts { const element = node; switch (element.name.kind) { case SyntaxKind.Identifier: - return getLiteralType(unescapeLeadingUnderscores(element.name.escapedText)); + return getLiteralType(idText(element.name)); case SyntaxKind.NumericLiteral: case SyntaxKind.StringLiteral: return getLiteralType(element.name.text); @@ -18593,7 +18588,7 @@ namespace ts { memberName = member.name.text; break; case SyntaxKind.Identifier: - memberName = unescapeLeadingUnderscores(member.name.escapedText); + memberName = idText(member.name); break; default: continue; @@ -19572,7 +19567,7 @@ namespace ts { const collidingSymbol = getSymbol(node.locals, rootName.escapedText, SymbolFlags.Value); if (collidingSymbol) { error(collidingSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, - unescapeLeadingUnderscores(rootName.escapedText), + idText(rootName), entityNameToString(promiseConstructorName)); return unknownType; } @@ -19971,11 +19966,11 @@ namespace ts { !isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) { - error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, unescapeLeadingUnderscores(local.escapedName)); + error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)); } } else if (compilerOptions.noUnusedLocals) { - forEach(local.declarations, d => errorUnusedLocal(d, unescapeLeadingUnderscores(local.escapedName))); + forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local))); } } }); @@ -20010,7 +20005,7 @@ namespace ts { } function isIdentifierThatStartsWithUnderScore(node: Node) { - return node.kind === SyntaxKind.Identifier && unescapeLeadingUnderscores((node).escapedText).charCodeAt(0) === CharacterCodes._; + return node.kind === SyntaxKind.Identifier && idText(node).charCodeAt(0) === CharacterCodes._; } function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { @@ -20019,13 +20014,13 @@ namespace ts { for (const member of node.members) { if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, unescapeLeadingUnderscores(member.symbol.escapedName)); + error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); } } else if (member.kind === SyntaxKind.Constructor) { for (const parameter of (member).parameters) { if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { - error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, unescapeLeadingUnderscores(parameter.symbol.escapedName)); + error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); } } } @@ -20046,7 +20041,7 @@ namespace ts { } for (const typeParameter of node.typeParameters) { if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { - error(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, unescapeLeadingUnderscores(typeParameter.symbol.escapedName)); + error(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)); } } } @@ -20059,7 +20054,7 @@ namespace ts { if (!local.isReferenced && !local.exportSymbol) { for (const declaration of local.declarations) { if (!isAmbientModule(declaration)) { - errorUnusedLocal(declaration, unescapeLeadingUnderscores(local.escapedName)); + errorUnusedLocal(declaration, symbolName(local)); } } } @@ -22354,7 +22349,7 @@ namespace ts { const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { - error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, unescapeLeadingUnderscores(exportedName.escapedText)); + error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName)); } else { markExportAsReferenced(node); @@ -25022,7 +25017,7 @@ namespace ts { function checkESModuleMarker(name: Identifier | BindingPattern): boolean { if (name.kind === SyntaxKind.Identifier) { - if (unescapeLeadingUnderscores(name.escapedText) === "__esModule") { + if (idText(name) === "__esModule") { return grammarErrorOnNode(name, Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules); } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d458e7e5ef5..8083b3841c8 100755 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2766,7 +2766,7 @@ namespace ts { return generateName(node); } else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) { - return unescapeLeadingUnderscores(node.escapedText); + return idText(node); } else if (node.kind === SyntaxKind.StringLiteral && (node).textSourceNode) { return getTextOfNode((node).textSourceNode, includeTrivia); @@ -2986,7 +2986,7 @@ namespace ts { case GeneratedIdentifierKind.Loop: return makeTempVariableName(TempFlags._i); case GeneratedIdentifierKind.Unique: - return makeUniqueName(unescapeLeadingUnderscores(name.escapedText)); + return makeUniqueName(idText(name)); } Debug.fail("Unsupported GeneratedIdentifierKind."); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 2ba2408225e..6dcf9fab067 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -126,7 +126,7 @@ namespace ts { export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier { return node.typeArguments !== typeArguments - ? updateNode(createIdentifier(unescapeLeadingUnderscores(node.escapedText), typeArguments), node) + ? updateNode(createIdentifier(idText(node), typeArguments), node) : node; } @@ -2951,12 +2951,12 @@ namespace ts { function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression { if (isQualifiedName(jsxFactory)) { const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent); - const right = createIdentifier(unescapeLeadingUnderscores(jsxFactory.right.escapedText)); + const right = createIdentifier(idText(jsxFactory.right)); right.escapedText = jsxFactory.right.escapedText; return createPropertyAccess(left, right); } else { - return createReactNamespace(unescapeLeadingUnderscores(jsxFactory.escapedText), parent); + return createReactNamespace(idText(jsxFactory), parent); } } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 0fea3e41c87..a283275d066 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -418,7 +418,7 @@ namespace ts { return createElementAccess(value, argumentExpression); } else { - const name = createIdentifier(unescapeLeadingUnderscores(propertyName.escapedText)); + const name = createIdentifier(idText(propertyName)); return createPropertyAccess(value, name); } } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index e9c84be5176..9d10120471e 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -609,7 +609,7 @@ namespace ts { // - break/continue is non-labeled and located in non-converted loop/switch statement const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue; const canUseBreakOrContinue = - (node.label && convertedLoopState.labels && convertedLoopState.labels.get(unescapeLeadingUnderscores(node.label.escapedText))) || + (node.label && convertedLoopState.labels && convertedLoopState.labels.get(idText(node.label))) || (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump)); if (!canUseBreakOrContinue) { @@ -628,11 +628,11 @@ namespace ts { else { if (node.kind === SyntaxKind.BreakStatement) { labelMarker = `break-${node.label.escapedText}`; - setLabeledJump(convertedLoopState, /*isBreak*/ true, unescapeLeadingUnderscores(node.label.escapedText), labelMarker); + setLabeledJump(convertedLoopState, /*isBreak*/ true, idText(node.label), labelMarker); } else { labelMarker = `continue-${node.label.escapedText}`; - setLabeledJump(convertedLoopState, /*isBreak*/ false, unescapeLeadingUnderscores(node.label.escapedText), labelMarker); + setLabeledJump(convertedLoopState, /*isBreak*/ false, idText(node.label), labelMarker); } } let returnExpression: Expression = createLiteral(labelMarker); @@ -2187,11 +2187,11 @@ namespace ts { } function recordLabel(node: LabeledStatement) { - convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), true); + convertedLoopState.labels.set(idText(node.label), true); } function resetLabel(node: LabeledStatement) { - convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), false); + convertedLoopState.labels.set(idText(node.label), false); } function visitLabeledStatement(node: LabeledStatement): VisitResult { @@ -3004,7 +3004,7 @@ namespace ts { else { loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name)); if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) { - const outParamName = createUniqueName("out_" + unescapeLeadingUnderscores(name.escapedText)); + const outParamName = createUniqueName("out_" + idText(name)); loopOutParameters.push({ originalName: name, outParamName }); } } diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 90c9063c140..d98f227e8c7 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -363,7 +363,7 @@ namespace ts { function substitutePropertyAccessExpression(node: PropertyAccessExpression) { if (node.expression.kind === SyntaxKind.SuperKeyword) { return createSuperAccessInAsyncMethod( - createLiteral(unescapeLeadingUnderscores(node.name.escapedText)), + createLiteral(idText(node.name)), node ); } diff --git a/src/compiler/transformers/es5.ts b/src/compiler/transformers/es5.ts index 290c9ae77c8..bc6ee13520f 100644 --- a/src/compiler/transformers/es5.ts +++ b/src/compiler/transformers/es5.ts @@ -111,7 +111,7 @@ namespace ts { * @param name An Identifier */ function trySubstituteReservedName(name: Identifier) { - const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(unescapeLeadingUnderscores(name.escapedText)) : undefined); + const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(idText(name)) : undefined); if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) { return setTextRange(createLiteral(name), name); } diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 0fca09b4540..97b555e01b7 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -790,7 +790,7 @@ namespace ts { function substitutePropertyAccessExpression(node: PropertyAccessExpression) { if (node.expression.kind === SyntaxKind.SuperKeyword) { return createSuperAccessInAsyncMethod( - createLiteral(unescapeLeadingUnderscores(node.name.escapedText)), + createLiteral(idText(node.name)), node ); } diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 06ecae3a63f..84ed997a70e 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1634,7 +1634,7 @@ namespace ts { } function transformAndEmitContinueStatement(node: ContinueStatement): void { - const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined); + const label = findContinueTarget(node.label ? idText(node.label) : undefined); if (label > 0) { emitBreak(label, /*location*/ node); } @@ -1646,7 +1646,7 @@ namespace ts { function visitContinueStatement(node: ContinueStatement): Statement { if (inStatementContainingYield) { - const label = findContinueTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText)); + const label = findContinueTarget(node.label && idText(node.label)); if (label > 0) { return createInlineBreak(label, /*location*/ node); } @@ -1656,7 +1656,7 @@ namespace ts { } function transformAndEmitBreakStatement(node: BreakStatement): void { - const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined); + const label = findBreakTarget(node.label ? idText(node.label) : undefined); if (label > 0) { emitBreak(label, /*location*/ node); } @@ -1668,7 +1668,7 @@ namespace ts { function visitBreakStatement(node: BreakStatement): Statement { if (inStatementContainingYield) { - const label = findBreakTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText)); + const label = findBreakTarget(node.label && idText(node.label)); if (label > 0) { return createInlineBreak(label, /*location*/ node); } @@ -1847,7 +1847,7 @@ namespace ts { // /*body*/ // .endlabeled // .mark endLabel - beginLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText)); + beginLabeledBlock(idText(node.label)); transformAndEmitEmbeddedStatement(node.statement); endLabeledBlock(); } @@ -1858,7 +1858,7 @@ namespace ts { function visitLabeledStatement(node: LabeledStatement) { if (inStatementContainingYield) { - beginScriptLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText)); + beginScriptLabeledBlock(idText(node.label)); } node = visitEachChild(node, visitor, context); @@ -1959,7 +1959,7 @@ namespace ts { } function substituteExpressionIdentifier(node: Identifier) { - if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(unescapeLeadingUnderscores(node.escapedText))) { + if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(idText(node))) { const original = getOriginalNode(node); if (isIdentifier(original) && original.parent) { const declaration = resolver.getReferencedValueDeclaration(original); @@ -2128,7 +2128,7 @@ namespace ts { hoistVariableDeclaration(variable.name); } else { - const text = unescapeLeadingUnderscores((variable.name).escapedText); + const text = idText(variable.name); name = declareLocal(text); if (!renamedCatchVariables) { renamedCatchVariables = createMap(); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 0d00f4d48a3..bbe05afe878 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -253,7 +253,7 @@ namespace ts { else { const name = (node).tagName; if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { - return createLiteral(unescapeLeadingUnderscores(name.escapedText)); + return createLiteral(idText(name)); } else { return createExpressionFromEntityName(name); @@ -268,11 +268,12 @@ namespace ts { */ function getAttributeName(node: JsxAttribute): StringLiteral | Identifier { const name = node.name; - if (/^[A-Za-z_]\w*$/.test(unescapeLeadingUnderscores(name.escapedText))) { + const text = idText(name); + if (/^[A-Za-z_]\w*$/.test(text)) { return name; } else { - return createLiteral(unescapeLeadingUnderscores(name.escapedText)); + return createLiteral(text); } } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 08c1fccfe16..145ac07c2f2 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1231,7 +1231,7 @@ namespace ts { */ function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined { const name = getDeclarationName(decl); - const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText)); + const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(idText(name)); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 8c47ec82f70..af77c499e8d 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -353,7 +353,7 @@ namespace ts { // write name of indirectly exported entry, i.e. 'export {x} from ...' exportedNames.push( createPropertyAssignment( - createLiteral(unescapeLeadingUnderscores((element.name || element.propertyName).escapedText)), + createLiteral(idText(element.name || element.propertyName)), createTrue() ) ); @@ -504,10 +504,10 @@ namespace ts { for (const e of (entry).exportClause.elements) { properties.push( createPropertyAssignment( - createLiteral(unescapeLeadingUnderscores(e.name.escapedText)), + createLiteral(idText(e.name)), createElementAccess( parameterName, - createLiteral(unescapeLeadingUnderscores((e.propertyName || e.name).escapedText)) + createLiteral(idText(e.propertyName || e.name)) ) ) ); @@ -1028,7 +1028,7 @@ namespace ts { let excludeName: string; if (exportSelf) { statements = appendExportStatement(statements, decl.name, getLocalName(decl)); - excludeName = unescapeLeadingUnderscores(decl.name.escapedText); + excludeName = idText(decl.name); } statements = appendExportsOfDeclaration(statements, decl, excludeName); @@ -1080,7 +1080,7 @@ namespace ts { } const name = getDeclarationName(decl); - const exportSpecifiers = moduleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText)); + const exportSpecifiers = moduleInfo.exportSpecifiers.get(idText(name)); if (exportSpecifiers) { for (const exportSpecifier of exportSpecifiers) { if (exportSpecifier.name.escapedText !== excludeName) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 8640c642675..4feb3ca0c26 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2038,7 +2038,7 @@ namespace ts { : (name).expression; } else if (isIdentifier(name)) { - return createLiteral(unescapeLeadingUnderscores(name.escapedText)); + return createLiteral(idText(name)); } else { return getSynthesizedClone(name); @@ -3240,7 +3240,7 @@ namespace ts { function getClassAliasIfNeeded(node: ClassDeclaration) { if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { enableSubstitutionForClassAliases(); - const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeLeadingUnderscores(node.name.escapedText) : "default"); + const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? idText(node.name) : "default"); classAliases[getOriginalNodeId(node)] = classAlias; hoistVariableDeclaration(classAlias); return classAlias; diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index f641ee49faf..00a0753eaa1 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -58,9 +58,9 @@ namespace ts { else { // export { x, y } for (const specifier of (node).exportClause.elements) { - if (!uniqueExports.get(unescapeLeadingUnderscores(specifier.name.escapedText))) { + if (!uniqueExports.get(idText(specifier.name))) { const name = specifier.propertyName || specifier.name; - exportSpecifiers.add(unescapeLeadingUnderscores(name.escapedText), specifier); + exportSpecifiers.add(idText(name), specifier); const decl = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name); @@ -69,7 +69,7 @@ namespace ts { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); } - uniqueExports.set(unescapeLeadingUnderscores(specifier.name.escapedText), true); + uniqueExports.set(idText(specifier.name), true); exportedNames = append(exportedNames, specifier.name); } } @@ -103,9 +103,9 @@ namespace ts { else { // export function x() { } const name = (node).name; - if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) { + if (!uniqueExports.get(idText(name))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true); + uniqueExports.set(idText(name), true); exportedNames = append(exportedNames, name); } } @@ -124,9 +124,9 @@ namespace ts { else { // export class x { } const name = (node).name; - if (name && !uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) { + if (name && !uniqueExports.get(idText(name))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); - uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true); + uniqueExports.set(idText(name), true); exportedNames = append(exportedNames, name); } } @@ -158,8 +158,9 @@ namespace ts { } } else if (!isGeneratedIdentifier(decl.name)) { - if (!uniqueExports.get(unescapeLeadingUnderscores(decl.name.escapedText))) { - uniqueExports.set(unescapeLeadingUnderscores(decl.name.escapedText), true); + const text = idText(decl.name); + if (!uniqueExports.get(text)) { + uniqueExports.set(text, true); exportedNames = append(exportedNames, decl.name); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e7d973865fb..23888f0b6d5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -560,7 +560,7 @@ namespace ts { export function entityNameToString(name: EntityNameOrEntityNameExpression): string { switch (name.kind) { case SyntaxKind.Identifier: - return getFullWidth(name) === 0 ? unescapeLeadingUnderscores(name.escapedText) : getTextOfNode(name); + return getFullWidth(name) === 0 ? idText(name) : getTextOfNode(name); case SyntaxKind.QualifiedName: return entityNameToString(name.left) + "." + entityNameToString(name.right); case SyntaxKind.PropertyAccessExpression: @@ -1976,8 +1976,7 @@ namespace ts { if (name.kind === SyntaxKind.ComputedPropertyName) { const nameExpression = name.expression; if (isWellKnownSymbolSyntactically(nameExpression)) { - const rightHandSideName = (nameExpression).name.escapedText; - return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores(rightHandSideName)); + return getPropertyNameForKnownSymbolName(idText((nameExpression).name)); } else if (nameExpression.kind === SyntaxKind.StringLiteral || nameExpression.kind === SyntaxKind.NumericLiteral) { return escapeLeadingUnderscores((nameExpression).text); @@ -1990,7 +1989,7 @@ namespace ts { export function getTextOfIdentifierOrLiteral(node: Identifier | LiteralLikeNode) { if (node) { if (node.kind === SyntaxKind.Identifier) { - return unescapeLeadingUnderscores((node as Identifier).escapedText); + return idText(node as Identifier); } if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) { @@ -3946,6 +3945,13 @@ namespace ts { return id.length >= 3 && id.charCodeAt(0) === CharacterCodes._ && id.charCodeAt(1) === CharacterCodes._ && id.charCodeAt(2) === CharacterCodes._ ? id.substr(1) : id; } + export function idText(identifier: Identifier): string { + return unescapeLeadingUnderscores(identifier.escapedText); + } + export function symbolName(symbol: Symbol): string { + return unescapeLeadingUnderscores(symbol.escapedName); + } + /** * Remove extra underscore from escaped identifier text content. * @deprecated Use `id.text` for the unescaped text. diff --git a/src/services/services.ts b/src/services/services.ts index 90f9acd82ea..0dfbd56f8d8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -327,7 +327,7 @@ namespace ts { } get name(): string { - return unescapeLeadingUnderscores(this.escapedName); + return symbolName(this); } getEscapedName(): __String { @@ -383,7 +383,7 @@ namespace ts { } get text(): string { - return unescapeLeadingUnderscores(this.escapedText); + return idText(this); } } IdentifierObject.prototype.kind = SyntaxKind.Identifier;