mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Created a branded type for identifier-escaped strings (#16915)
* Created a branded type for escaped strings Then flowed it throughout the compiler, finding and fixing a handful of bugs relating to underscore-prefixed identifiers in the process. Includes a test for two cases noticed - diagnostics from conflicting symbols from export *'s, and enum with underscore prefixed member emit. * Correctly double underscores WRT mapped types * Add fourslash tests for other fixed issues * use function call over cast * Update forEachEntry type accuracy * Just use escaped names for ActiveLabel * Remove casts from getPropertyNameForPropertyNameNode * This pattern has occurred a few times, could use a helper function. * Remove duplicated helper * Remove unneeded check, use helper * Identifiers list is no longer escaped strings * Extract repeated string-getting code into helper * Rename type and associated functions * Make getName() return UnderscoreEscapedString, add getUnescapedName() * Add list of internal symbol names to escaped string type to cut back on casting * Remove outdated comments * Reassign interned values to nodes, just in case * Swap to string enum * Add deprecated aliases to escapeIdentifier and unescapeIdentifier * Add temp var * Remove unsafe casts * Rename escaped string type as per @sandersn's suggestion, fix string enum usages * Reorganize double underscore tests * Remove jfreeman from TODO * Remove unneeded parenthesis
This commit is contained in:
+54
-53
@@ -10,7 +10,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface ActiveLabel {
|
||||
name: string;
|
||||
name: __String;
|
||||
breakTarget: FlowLabel;
|
||||
continueTarget: FlowLabel;
|
||||
referenced: boolean;
|
||||
@@ -132,8 +132,8 @@ namespace ts {
|
||||
let inStrictMode: boolean;
|
||||
|
||||
let symbolCount = 0;
|
||||
let Symbol: { new (flags: SymbolFlags, name: string): Symbol };
|
||||
let classifiableNames: Map<string>;
|
||||
let Symbol: { new (flags: SymbolFlags, name: __String): Symbol };
|
||||
let classifiableNames: UnderscoreEscapedMap<__String>;
|
||||
|
||||
const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
@@ -147,7 +147,7 @@ namespace ts {
|
||||
options = opts;
|
||||
languageVersion = getEmitScriptTarget(options);
|
||||
inStrictMode = bindInStrictMode(file, opts);
|
||||
classifiableNames = createMap<string>();
|
||||
classifiableNames = createUnderscoreEscapedMap<__String>();
|
||||
symbolCount = 0;
|
||||
skipTransformFlagAggregation = file.isDeclarationFile;
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createSymbol(flags: SymbolFlags, name: string): Symbol {
|
||||
function createSymbol(flags: SymbolFlags, name: __String): Symbol {
|
||||
symbolCount++;
|
||||
return new Symbol(flags, name);
|
||||
}
|
||||
@@ -207,11 +207,11 @@ namespace ts {
|
||||
symbol.declarations.push(node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
symbol.exports = createMap<Symbol>();
|
||||
symbol.exports = createSymbolTable();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
|
||||
symbol.members = createMap<Symbol>();
|
||||
symbol.members = createSymbolTable();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
@@ -226,62 +226,63 @@ namespace ts {
|
||||
|
||||
// Should not be called on a declaration with a computed property name,
|
||||
// unless it is a well known Symbol.
|
||||
function getDeclarationName(node: Declaration): string {
|
||||
function getDeclarationName(node: Declaration): __String {
|
||||
const name = getNameOfDeclaration(node);
|
||||
if (name) {
|
||||
if (isAmbientModule(node)) {
|
||||
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>name).text}"`;
|
||||
const moduleName = getTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
|
||||
return (isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${moduleName}"`) as __String;
|
||||
}
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>name).expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return nameExpression.text;
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
}
|
||||
|
||||
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
|
||||
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
|
||||
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores((<PropertyAccessExpression>nameExpression).name.text));
|
||||
}
|
||||
return (<Identifier | LiteralExpression>name).text;
|
||||
return getEscapedTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
return "__constructor";
|
||||
return InternalSymbolName.Constructor;
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.CallSignature:
|
||||
return "__call";
|
||||
return InternalSymbolName.Call;
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
return "__new";
|
||||
return InternalSymbolName.New;
|
||||
case SyntaxKind.IndexSignature:
|
||||
return "__index";
|
||||
return InternalSymbolName.Index;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return "__export";
|
||||
return InternalSymbolName.ExportStar;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return (<ExportAssignment>node).isExportEquals ? "export=" : "default";
|
||||
return (<ExportAssignment>node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) {
|
||||
// module.exports = ...
|
||||
return "export=";
|
||||
return InternalSymbolName.ExportEquals;
|
||||
}
|
||||
Debug.fail("Unknown binary declaration kind");
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return hasModifier(node, ModifierFlags.Default) ? "default" : undefined;
|
||||
return (hasModifier(node, ModifierFlags.Default) ? InternalSymbolName.Default : undefined);
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return isJSDocConstructSignature(node) ? "__new" : "__call";
|
||||
return (isJSDocConstructSignature(node) ? InternalSymbolName.New : InternalSymbolName.Call);
|
||||
case SyntaxKind.Parameter:
|
||||
// Parameters with names are handled at the top of this function. Parameters
|
||||
// without names can only come from JSDocFunctionTypes.
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType);
|
||||
const functionType = <JSDocFunctionType>node.parent;
|
||||
const index = indexOf(functionType.parameters, node);
|
||||
return "arg" + index;
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
let nameFromParentNode: string;
|
||||
let nameFromParentNode: __String;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
|
||||
@@ -295,7 +296,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDisplayName(node: Declaration): string {
|
||||
return (node as NamedDeclaration).name ? declarationNameToString((node as NamedDeclaration).name) : getDeclarationName(node);
|
||||
return (node as NamedDeclaration).name ? declarationNameToString((node as NamedDeclaration).name) : unescapeLeadingUnderscores(getDeclarationName(node));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,11 +313,11 @@ namespace ts {
|
||||
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
|
||||
|
||||
// The exported symbol for an export default function/class node is always named "default"
|
||||
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
|
||||
const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node);
|
||||
|
||||
let symbol: Symbol;
|
||||
if (name === undefined) {
|
||||
symbol = createSymbol(SymbolFlags.None, "__missing");
|
||||
symbol = createSymbol(SymbolFlags.None, InternalSymbolName.Missing);
|
||||
}
|
||||
else {
|
||||
// Check and see if the symbol table already has a symbol with this name. If not,
|
||||
@@ -481,7 +482,7 @@ namespace ts {
|
||||
if (containerFlags & ContainerFlags.IsContainer) {
|
||||
container = blockScopeContainer = node;
|
||||
if (containerFlags & ContainerFlags.HasLocals) {
|
||||
container.locals = createMap<Symbol>();
|
||||
container.locals = createSymbolTable();
|
||||
}
|
||||
addToContainerChain(container);
|
||||
}
|
||||
@@ -1006,7 +1007,7 @@ namespace ts {
|
||||
currentFlow = unreachableFlow;
|
||||
}
|
||||
|
||||
function findActiveLabel(name: string) {
|
||||
function findActiveLabel(name: __String) {
|
||||
if (activeLabels) {
|
||||
for (const label of activeLabels) {
|
||||
if (label.name === name) {
|
||||
@@ -1169,7 +1170,7 @@ namespace ts {
|
||||
bindEach(node.statements);
|
||||
}
|
||||
|
||||
function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
|
||||
function pushActiveLabel(name: __String, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
|
||||
const activeLabel = {
|
||||
name,
|
||||
breakTarget,
|
||||
@@ -1645,9 +1646,9 @@ namespace ts {
|
||||
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
|
||||
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
|
||||
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||
typeLiteralSymbol.members = createMap<Symbol>();
|
||||
typeLiteralSymbol.members = createSymbolTable();
|
||||
typeLiteralSymbol.members.set(symbol.name, symbol);
|
||||
}
|
||||
|
||||
@@ -1658,14 +1659,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (inStrictMode) {
|
||||
const seen = createMap<ElementKind>();
|
||||
const seen = createUnderscoreEscapedMap<ElementKind>();
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const identifier = <Identifier>prop.name;
|
||||
const identifier = prop.name;
|
||||
|
||||
// ECMA-262 11.1.5 Object Initializer
|
||||
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
|
||||
@@ -1693,18 +1694,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.Object);
|
||||
}
|
||||
|
||||
function bindJsxAttributes(node: JsxAttributes) {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes");
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.JSXAttributes);
|
||||
}
|
||||
|
||||
function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: __String) {
|
||||
const symbol = createSymbol(symbolFlags, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||
}
|
||||
@@ -1722,7 +1723,7 @@ namespace ts {
|
||||
// falls through
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = createMap<Symbol>();
|
||||
blockScopeContainer.locals = createSymbolTable();
|
||||
addToContainerChain(blockScopeContainer);
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
@@ -1803,7 +1804,7 @@ namespace ts {
|
||||
// otherwise report generic error message.
|
||||
const span = getErrorSpanForNode(file, name);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
|
||||
getStrictModeEvalOrArgumentsMessage(contextNode), unescapeLeadingUnderscores(identifier.text)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1895,8 +1896,8 @@ namespace ts {
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
||||
}
|
||||
|
||||
function getDestructuringParameterName(node: Declaration) {
|
||||
return "__" + indexOf((<SignatureDeclaration>node.parent).parameters, node);
|
||||
function getDestructuringParameterName(node: Declaration): __String {
|
||||
return "__" + indexOf((<SignatureDeclaration>node.parent).parameters, node) as __String;
|
||||
}
|
||||
|
||||
function bind(node: Node): void {
|
||||
@@ -2190,7 +2191,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral | JSDocRecordType) {
|
||||
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, "__type");
|
||||
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
}
|
||||
|
||||
function checkTypePredicate(node: TypePredicateNode) {
|
||||
@@ -2212,7 +2213,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindSourceFileAsExternalModule() {
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`);
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String);
|
||||
}
|
||||
|
||||
function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
|
||||
@@ -2256,7 +2257,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
file.symbol.globalExports = file.symbol.globalExports || createMap<Symbol>();
|
||||
file.symbol.globalExports = file.symbol.globalExports || createSymbolTable();
|
||||
declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
@@ -2341,7 +2342,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
container.symbol.members = container.symbol.members || createSymbolTable();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
break;
|
||||
@@ -2403,11 +2404,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function lookupSymbolForName(name: string) {
|
||||
function lookupSymbolForName(name: __String) {
|
||||
return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
function bindPropertyAssignment(functionName: __String, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
let targetSymbol = lookupSymbolForName(functionName);
|
||||
|
||||
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
|
||||
@@ -2420,8 +2421,8 @@ namespace ts {
|
||||
|
||||
// Set up the members collection if it doesn't exist already
|
||||
const symbolTable = isPrototypeProperty ?
|
||||
(targetSymbol.members || (targetSymbol.members = createMap<Symbol>())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createMap<Symbol>()));
|
||||
(targetSymbol.members || (targetSymbol.members = createSymbolTable())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createSymbolTable()));
|
||||
|
||||
// Declare the method/property
|
||||
declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
@@ -2440,7 +2441,7 @@ namespace ts {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
}
|
||||
else {
|
||||
const bindingName = node.name ? node.name.text : "__class";
|
||||
const bindingName = node.name ? node.name.text : InternalSymbolName.Class;
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
||||
// Add name of class expression into the map for semantic classifier
|
||||
if (node.name) {
|
||||
@@ -2459,13 +2460,13 @@ namespace ts {
|
||||
// Note: we check for this here because this class may be merging into a module. The
|
||||
// module might have an exported variable called 'prototype'. We can't allow that as
|
||||
// that would clash with the built-in 'prototype' for the class.
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype" as __String);
|
||||
const symbolExport = symbol.exports.get(prototypeSymbol.name);
|
||||
if (symbolExport) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(prototypeSymbol.name)));
|
||||
}
|
||||
symbol.exports.set(prototypeSymbol.name, prototypeSymbol);
|
||||
prototypeSymbol.parent = symbol;
|
||||
@@ -2553,7 +2554,7 @@ namespace ts {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
checkStrictModeFunctionName(node);
|
||||
const bindingName = node.name ? node.name.text : "__function";
|
||||
const bindingName = node.name ? node.name.text : InternalSymbolName.Function;
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
|
||||
}
|
||||
|
||||
@@ -2567,7 +2568,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
return hasDynamicName(node)
|
||||
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
|
||||
? bindAnonymousDeclaration(node, symbolFlags, InternalSymbolName.Computed)
|
||||
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
|
||||
+250
-251
File diff suppressed because it is too large
Load Diff
@@ -1047,7 +1047,7 @@ namespace ts {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, Diagnostics.String_literal_with_double_quotes_expected));
|
||||
}
|
||||
|
||||
const keyText = getTextOfPropertyName(element.name);
|
||||
const keyText = unescapeLeadingUnderscores(getTextOfPropertyName(element.name));
|
||||
const option = knownOptions ? knownOptions.get(keyText) : undefined;
|
||||
if (extraKeyDiagnosticMessage && !option) {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
|
||||
|
||||
+35
-11
@@ -47,6 +47,22 @@ namespace ts {
|
||||
return new MapCtr<T>();
|
||||
}
|
||||
|
||||
/** Create a new escaped identifier map. */
|
||||
export function createUnderscoreEscapedMap<T>(): UnderscoreEscapedMap<T> {
|
||||
return new MapCtr<T>() as UnderscoreEscapedMap<T>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createSymbolTable(symbols?: Symbol[]): SymbolTable {
|
||||
const result = createMap<Symbol>() as SymbolTable;
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
result.set(symbol.name, symbol);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createMapFromTemplate<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = new MapCtr<T>();
|
||||
|
||||
@@ -1000,11 +1016,13 @@ namespace ts {
|
||||
* Calls `callback` for each entry in the map, returning the first truthy result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
*/
|
||||
export function forEachEntry<T, U>(map: Map<T>, callback: (value: T, key: string) => U | undefined): U | undefined {
|
||||
export function forEachEntry<T, U>(map: UnderscoreEscapedMap<T>, callback: (value: T, key: __String) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: Map<T>, callback: (value: T, key: string) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: UnderscoreEscapedMap<T> | Map<T>, callback: (value: T, key: (string & __String)) => U | undefined): U | undefined {
|
||||
const iterator = map.entries();
|
||||
for (let { value: pair, done } = iterator.next(); !done; { value: pair, done } = iterator.next()) {
|
||||
const [key, value] = pair;
|
||||
const result = callback(value, key);
|
||||
const result = callback(value, key as (string & __String));
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -1013,10 +1031,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** `forEachEntry` for just keys. */
|
||||
export function forEachKey<T>(map: Map<{}>, callback: (key: string) => T | undefined): T | undefined {
|
||||
export function forEachKey<T>(map: UnderscoreEscapedMap<{}>, callback: (key: __String) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: Map<{}>, callback: (key: string) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: UnderscoreEscapedMap<{}> | Map<{}>, callback: (key: string & __String) => T | undefined): T | undefined {
|
||||
const iterator = map.keys();
|
||||
for (let { value: key, done } = iterator.next(); !done; { value: key, done } = iterator.next()) {
|
||||
const result = callback(key);
|
||||
const result = callback(key as string & __String);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -1025,9 +1045,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Copy entries from `source` to `target`. */
|
||||
export function copyEntries<T>(source: Map<T>, target: Map<T>): void {
|
||||
source.forEach((value, key) => {
|
||||
target.set(key, value);
|
||||
export function copyEntries<T>(source: UnderscoreEscapedMap<T>, target: UnderscoreEscapedMap<T>): void;
|
||||
export function copyEntries<T>(source: Map<T>, target: Map<T>): void;
|
||||
export function copyEntries<T, U extends UnderscoreEscapedMap<T> | Map<T>>(source: U, target: U): void {
|
||||
(source as Map<T>).forEach((value, key) => {
|
||||
(target as Map<T>).set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1099,9 +1121,11 @@ namespace ts {
|
||||
return arrayToMap<T, true>(array, makeKey, () => true);
|
||||
}
|
||||
|
||||
export function cloneMap<T>(map: Map<T>) {
|
||||
export function cloneMap(map: SymbolTable): SymbolTable;
|
||||
export function cloneMap<T>(map: Map<T>): Map<T>;
|
||||
export function cloneMap<T>(map: Map<T> | SymbolTable): Map<T> | SymbolTable {
|
||||
const clone = createMap<T>();
|
||||
copyEntries(map, clone);
|
||||
copyEntries(map as Map<T>, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -2272,13 +2296,13 @@ namespace ts {
|
||||
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos?: number, end?: number) => Token<TKind>;
|
||||
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
|
||||
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol;
|
||||
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
||||
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
||||
getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource;
|
||||
}
|
||||
|
||||
function Symbol(this: Symbol, flags: SymbolFlags, name: string) {
|
||||
function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
|
||||
this.flags = flags;
|
||||
this.name = name;
|
||||
this.declarations = undefined;
|
||||
|
||||
@@ -2761,7 +2761,7 @@ namespace ts {
|
||||
return generateName(node);
|
||||
}
|
||||
else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
||||
return unescapeIdentifier(node.text);
|
||||
return unescapeLeadingUnderscores(node.text);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
|
||||
return getTextOfNode((<StringLiteral>node).textSourceNode, includeTrivia);
|
||||
@@ -2818,13 +2818,13 @@ namespace ts {
|
||||
// Auto, Loop, and Unique names are cached based on their unique
|
||||
// autoGenerateId.
|
||||
const autoGenerateId = name.autoGenerateId;
|
||||
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = unescapeIdentifier(makeName(name)));
|
||||
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameCached(node: Node) {
|
||||
const nodeId = getNodeId(node);
|
||||
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node)));
|
||||
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2843,7 +2843,7 @@ namespace ts {
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals) {
|
||||
const local = node.locals.get(name);
|
||||
const local = node.locals.get(escapeLeadingUnderscores(name));
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
@@ -2918,7 +2918,7 @@ namespace ts {
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
const expr = getExternalModuleName(node);
|
||||
const baseName = expr.kind === SyntaxKind.StringLiteral ?
|
||||
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
|
||||
makeIdentifierFromModuleName((<LiteralExpression>expr).text) : "module";
|
||||
return makeUniqueName(baseName);
|
||||
}
|
||||
|
||||
@@ -2981,7 +2981,7 @@ namespace ts {
|
||||
case GeneratedIdentifierKind.Loop:
|
||||
return makeTempVariableName(TempFlags._i);
|
||||
case GeneratedIdentifierKind.Unique:
|
||||
return makeUniqueName(unescapeIdentifier(name.text));
|
||||
return makeUniqueName(unescapeLeadingUnderscores(name.text));
|
||||
}
|
||||
|
||||
Debug.fail("Unsupported GeneratedIdentifierKind.");
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral {
|
||||
const node = createStringLiteral(sourceNode.text);
|
||||
const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode));
|
||||
node.textSourceNode = sourceNode;
|
||||
return node;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ namespace ts {
|
||||
export function createIdentifier(text: string, typeArguments: TypeNode[]): Identifier;
|
||||
export function createIdentifier(text: string, typeArguments?: TypeNode[]): Identifier {
|
||||
const node = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
node.text = escapeIdentifier(text);
|
||||
node.text = escapeLeadingUnderscores(text);
|
||||
node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown;
|
||||
node.autoGenerateKind = GeneratedIdentifierKind.None;
|
||||
node.autoGenerateId = 0;
|
||||
@@ -124,7 +124,7 @@ namespace ts {
|
||||
|
||||
export function updateIdentifier(node: Identifier, typeArguments: NodeArray<TypeNode> | undefined): Identifier {
|
||||
return node.typeArguments !== typeArguments
|
||||
? updateNode(createIdentifier(node.text, typeArguments), node)
|
||||
? updateNode(createIdentifier(unescapeLeadingUnderscores(node.text), typeArguments), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -2645,12 +2645,12 @@ namespace ts {
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
|
||||
if (isQualifiedName(jsxFactory)) {
|
||||
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
|
||||
const right = createIdentifier(jsxFactory.right.text);
|
||||
const right = createIdentifier(unescapeLeadingUnderscores(jsxFactory.right.text));
|
||||
right.text = jsxFactory.right.text;
|
||||
return createPropertyAccess(left, right);
|
||||
}
|
||||
else {
|
||||
return createReactNamespace(jsxFactory.text, parent);
|
||||
return createReactNamespace(unescapeLeadingUnderscores(jsxFactory.text), parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-13
@@ -1178,12 +1178,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = createNode(kind, scanner.getStartPos());
|
||||
(<Identifier>result).text = "";
|
||||
(<Identifier>result).text = "" as __String;
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function internIdentifier(text: string): string {
|
||||
text = escapeIdentifier(text);
|
||||
let identifier = identifiers.get(text);
|
||||
if (identifier === undefined) {
|
||||
identifiers.set(text, identifier = text);
|
||||
@@ -1203,7 +1202,7 @@ namespace ts {
|
||||
if (token() !== SyntaxKind.Identifier) {
|
||||
node.originalKeywordKind = token();
|
||||
}
|
||||
node.text = internIdentifier(scanner.getTokenValue());
|
||||
node.text = escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
|
||||
nextToken();
|
||||
return finishNode(node);
|
||||
}
|
||||
@@ -1227,7 +1226,9 @@ namespace ts {
|
||||
|
||||
function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName {
|
||||
if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral) {
|
||||
return <StringLiteral | NumericLiteral>parseLiteralNode(/*internName*/ true);
|
||||
const node = <StringLiteral | NumericLiteral>parseLiteralNode();
|
||||
node.text = internIdentifier(node.text);
|
||||
return node;
|
||||
}
|
||||
if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) {
|
||||
return parseComputedPropertyName();
|
||||
@@ -2049,26 +2050,26 @@ namespace ts {
|
||||
return finishNode(span);
|
||||
}
|
||||
|
||||
function parseLiteralNode(internName?: boolean): LiteralExpression {
|
||||
return <LiteralExpression>parseLiteralLikeNode(token(), internName);
|
||||
function parseLiteralNode(): LiteralExpression {
|
||||
return <LiteralExpression>parseLiteralLikeNode(token());
|
||||
}
|
||||
|
||||
function parseTemplateHead(): TemplateHead {
|
||||
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
|
||||
const fragment = parseLiteralLikeNode(token());
|
||||
Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
return <TemplateHead>fragment;
|
||||
}
|
||||
|
||||
function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail {
|
||||
const fragment = parseLiteralLikeNode(token(), /*internName*/ false);
|
||||
const fragment = parseLiteralLikeNode(token());
|
||||
Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind");
|
||||
return <TemplateMiddle | TemplateTail>fragment;
|
||||
}
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind, internName: boolean): LiteralLikeNode {
|
||||
function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode {
|
||||
const node = <LiteralExpression>createNode(kind);
|
||||
const text = scanner.getTokenValue();
|
||||
node.text = internName ? internIdentifier(text) : text;
|
||||
node.text = text;
|
||||
|
||||
if (scanner.hasExtendedUnicodeEscape()) {
|
||||
node.hasExtendedUnicodeEscape = true;
|
||||
@@ -5624,7 +5625,8 @@ namespace ts {
|
||||
node.flags |= NodeFlags.GlobalAugmentation;
|
||||
}
|
||||
else {
|
||||
node.name = <StringLiteral>parseLiteralNode(/*internName*/ true);
|
||||
node.name = <StringLiteral>parseLiteralNode();
|
||||
node.name.text = internIdentifier(node.name.text);
|
||||
}
|
||||
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
@@ -5768,7 +5770,7 @@ namespace ts {
|
||||
function parseModuleSpecifier(): Expression {
|
||||
if (token() === SyntaxKind.StringLiteral) {
|
||||
const result = parseLiteralNode();
|
||||
internIdentifier((<LiteralExpression>result).text);
|
||||
result.text = internIdentifier(result.text);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
@@ -6990,7 +6992,7 @@ namespace ts {
|
||||
const pos = scanner.getTokenPos();
|
||||
const end = scanner.getTextPos();
|
||||
const result = <Identifier>createNode(SyntaxKind.Identifier, pos);
|
||||
result.text = content.substring(pos, end);
|
||||
result.text = escapeLeadingUnderscores(content.substring(pos, end));
|
||||
finishNode(result, end);
|
||||
|
||||
nextJSDocToken();
|
||||
|
||||
@@ -405,7 +405,7 @@ namespace ts {
|
||||
let commonSourceDirectory: string;
|
||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
let classifiableNames: UnderscoreEscapedMap<__String>;
|
||||
let modifiedFilePaths: Path[] | undefined;
|
||||
|
||||
const cachedSemanticDiagnosticsForFile: DiagnosticCache = {};
|
||||
@@ -580,7 +580,7 @@ namespace ts {
|
||||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
getTypeChecker();
|
||||
classifiableNames = createMap<string>();
|
||||
classifiableNames = createUnderscoreEscapedMap<__String>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyEntries(sourceFile.classifiableNames, classifiableNames);
|
||||
|
||||
@@ -411,11 +411,11 @@ namespace ts {
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
const argumentExpression = getSynthesizedClone(propertyName);
|
||||
argumentExpression.text = unescapeIdentifier(argumentExpression.text);
|
||||
argumentExpression.text = argumentExpression.text;
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else {
|
||||
const name = createIdentifier(unescapeIdentifier(propertyName.text));
|
||||
const name = createIdentifier(unescapeLeadingUnderscores(propertyName.text));
|
||||
return createPropertyAccess(value, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,7 +661,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(node.label.text)) ||
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(unescapeLeadingUnderscores(node.label.text))) ||
|
||||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
|
||||
|
||||
if (!canUseBreakOrContinue) {
|
||||
@@ -680,11 +680,11 @@ namespace ts {
|
||||
else {
|
||||
if (node.kind === SyntaxKind.BreakStatement) {
|
||||
labelMarker = `break-${node.label.text}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, node.label.text, labelMarker);
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, unescapeLeadingUnderscores(node.label.text), labelMarker);
|
||||
}
|
||||
else {
|
||||
labelMarker = `continue-${node.label.text}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker);
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, unescapeLeadingUnderscores(node.label.text), labelMarker);
|
||||
}
|
||||
}
|
||||
let returnExpression: Expression = createLiteral(labelMarker);
|
||||
@@ -2236,11 +2236,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function recordLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(node.label.text, node.label.text);
|
||||
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.text), unescapeLeadingUnderscores(node.label.text));
|
||||
}
|
||||
|
||||
function resetLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(node.label.text, undefined);
|
||||
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.text), undefined);
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
|
||||
@@ -3053,7 +3053,7 @@ namespace ts {
|
||||
else {
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const outParamName = createUniqueName("out_" + unescapeIdentifier(name.text));
|
||||
const outParamName = createUniqueName("out_" + unescapeLeadingUnderscores(name.text));
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ namespace ts {
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(node.name.text)),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace ts {
|
||||
* @param name An Identifier
|
||||
*/
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(unescapeLeadingUnderscores(name.text)) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return setTextRange(createLiteral(name), name);
|
||||
}
|
||||
|
||||
@@ -776,7 +776,7 @@ namespace ts {
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(node.name.text)),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1635,14 +1635,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformAndEmitContinueStatement(node: ContinueStatement): void {
|
||||
const label = findContinueTarget(node.label ? node.label.text : undefined);
|
||||
const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.text) : undefined);
|
||||
Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
|
||||
emitBreak(label, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitContinueStatement(node: ContinueStatement): Statement {
|
||||
if (inStatementContainingYield) {
|
||||
const label = findContinueTarget(node.label && node.label.text);
|
||||
const label = findContinueTarget(node.label && unescapeLeadingUnderscores(node.label.text));
|
||||
if (label > 0) {
|
||||
return createInlineBreak(label, /*location*/ node);
|
||||
}
|
||||
@@ -1652,14 +1652,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformAndEmitBreakStatement(node: BreakStatement): void {
|
||||
const label = findBreakTarget(node.label ? node.label.text : undefined);
|
||||
const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.text) : undefined);
|
||||
Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
|
||||
emitBreak(label, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitBreakStatement(node: BreakStatement): Statement {
|
||||
if (inStatementContainingYield) {
|
||||
const label = findBreakTarget(node.label && node.label.text);
|
||||
const label = findBreakTarget(node.label && unescapeLeadingUnderscores(node.label.text));
|
||||
if (label > 0) {
|
||||
return createInlineBreak(label, /*location*/ node);
|
||||
}
|
||||
@@ -1838,7 +1838,7 @@ namespace ts {
|
||||
// /*body*/
|
||||
// .endlabeled
|
||||
// .mark endLabel
|
||||
beginLabeledBlock(node.label.text);
|
||||
beginLabeledBlock(unescapeLeadingUnderscores(node.label.text));
|
||||
transformAndEmitEmbeddedStatement(node.statement);
|
||||
endLabeledBlock();
|
||||
}
|
||||
@@ -1849,7 +1849,7 @@ namespace ts {
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement) {
|
||||
if (inStatementContainingYield) {
|
||||
beginScriptLabeledBlock(node.label.text);
|
||||
beginScriptLabeledBlock(unescapeLeadingUnderscores(node.label.text));
|
||||
}
|
||||
|
||||
node = visitEachChild(node, visitor, context);
|
||||
@@ -1950,7 +1950,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(unescapeLeadingUnderscores(node.text))) {
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
@@ -2123,7 +2123,7 @@ namespace ts {
|
||||
hoistVariableDeclaration(variable.name);
|
||||
}
|
||||
else {
|
||||
const text = (<Identifier>variable.name).text;
|
||||
const text = unescapeLeadingUnderscores((<Identifier>variable.name).text);
|
||||
name = declareLocal(text);
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
|
||||
@@ -253,7 +253,7 @@ namespace ts {
|
||||
else {
|
||||
const name = (<JsxOpeningLikeElement>node).tagName;
|
||||
if (isIdentifier(name) && isIntrinsicJsxName(name.text)) {
|
||||
return createLiteral(name.text);
|
||||
return createLiteral(unescapeLeadingUnderscores(name.text));
|
||||
}
|
||||
else {
|
||||
return createExpressionFromEntityName(name);
|
||||
@@ -268,11 +268,11 @@ namespace ts {
|
||||
*/
|
||||
function getAttributeName(node: JsxAttribute): StringLiteral | Identifier {
|
||||
const name = node.name;
|
||||
if (/^[A-Za-z_]\w*$/.test(name.text)) {
|
||||
if (/^[A-Za-z_]\w*$/.test(unescapeLeadingUnderscores(name.text))) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return createLiteral(name.text);
|
||||
return createLiteral(unescapeLeadingUnderscores(name.text));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1225,7 +1225,7 @@ namespace ts {
|
||||
*/
|
||||
function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined {
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(name.text);
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.text));
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
|
||||
|
||||
@@ -353,7 +353,7 @@ namespace ts {
|
||||
// write name of indirectly exported entry, i.e. 'export {x} from ...'
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral((element.name || element.propertyName).text),
|
||||
createLiteral(unescapeLeadingUnderscores((element.name || element.propertyName).text)),
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
@@ -504,10 +504,10 @@ namespace ts {
|
||||
for (const e of (<ExportDeclaration>entry).exportClause.elements) {
|
||||
properties.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(e.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(e.name.text)),
|
||||
createElementAccess(
|
||||
parameterName,
|
||||
createLiteral((e.propertyName || e.name).text)
|
||||
createLiteral(unescapeLeadingUnderscores((e.propertyName || e.name).text))
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -1028,7 +1028,7 @@ namespace ts {
|
||||
let excludeName: string;
|
||||
if (exportSelf) {
|
||||
statements = appendExportStatement(statements, decl.name, getLocalName(decl));
|
||||
excludeName = decl.name.text;
|
||||
excludeName = unescapeLeadingUnderscores(decl.name.text);
|
||||
}
|
||||
|
||||
statements = appendExportsOfDeclaration(statements, decl, excludeName);
|
||||
@@ -1055,7 +1055,7 @@ namespace ts {
|
||||
if (hasModifier(decl, ModifierFlags.Export)) {
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name;
|
||||
statements = appendExportStatement(statements, exportName, getLocalName(decl));
|
||||
excludeName = exportName.text;
|
||||
excludeName = getTextOfIdentifierOrLiteral(exportName);
|
||||
}
|
||||
|
||||
if (decl.name) {
|
||||
@@ -1080,7 +1080,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers.get(name.text);
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.text));
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
if (exportSpecifier.name.text !== excludeName) {
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace ts {
|
||||
let currentNamespace: ModuleDeclaration;
|
||||
let currentNamespaceContainerName: Identifier;
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentScopeFirstDeclarationsOfName: Map<Node>;
|
||||
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node>;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
@@ -2007,7 +2007,7 @@ namespace ts {
|
||||
: (<ComputedPropertyName>name).expression;
|
||||
}
|
||||
else if (isIdentifier(name)) {
|
||||
return createLiteral(unescapeIdentifier(name.text));
|
||||
return createLiteral(unescapeLeadingUnderscores(name.text));
|
||||
}
|
||||
else {
|
||||
return getSynthesizedClone(name);
|
||||
@@ -2647,7 +2647,7 @@ namespace ts {
|
||||
const name = node.symbol && node.symbol.name;
|
||||
if (name) {
|
||||
if (!currentScopeFirstDeclarationsOfName) {
|
||||
currentScopeFirstDeclarationsOfName = createMap<Node>();
|
||||
currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap<Node>();
|
||||
}
|
||||
|
||||
if (!currentScopeFirstDeclarationsOfName.has(name)) {
|
||||
@@ -3210,7 +3210,7 @@ namespace ts {
|
||||
function getClassAliasIfNeeded(node: ClassDeclaration) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
|
||||
enableSubstitutionForClassAliases();
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeIdentifier(node.name.text) : "default");
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeLeadingUnderscores(node.name.text) : "default");
|
||||
classAliases[getOriginalNodeId(node)] = classAlias;
|
||||
hoistVariableDeclaration(classAlias);
|
||||
return classAlias;
|
||||
|
||||
@@ -58,9 +58,9 @@ namespace ts {
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports.get(specifier.name.text)) {
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(specifier.name.text))) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(name.text, specifier);
|
||||
exportSpecifiers.add(unescapeLeadingUnderscores(name.text), specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
@@ -69,7 +69,7 @@ namespace ts {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports.set(specifier.name.text, true);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(specifier.name.text), true);
|
||||
exportedNames = append(exportedNames, specifier.name);
|
||||
}
|
||||
}
|
||||
@@ -103,9 +103,9 @@ namespace ts {
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.text))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.text), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
@@ -124,9 +124,9 @@ namespace ts {
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(name.text)) {
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.text))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(name.text, true);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.text), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
@@ -158,8 +158,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports.get(decl.name.text)) {
|
||||
uniqueExports.set(decl.name.text, true);
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(decl.name.text))) {
|
||||
uniqueExports.set(unescapeLeadingUnderscores(decl.name.text), true);
|
||||
exportedNames = append(exportedNames, decl.name);
|
||||
}
|
||||
}
|
||||
|
||||
+49
-5
@@ -589,7 +589,7 @@ namespace ts {
|
||||
* Text of identifier (with escapes converted to characters).
|
||||
* If the identifier begins with two underscores, this will begin with three.
|
||||
*/
|
||||
text: string;
|
||||
text: __String;
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
|
||||
@@ -2357,7 +2357,7 @@ namespace ts {
|
||||
// Stores a line map for the file.
|
||||
// This field should never be used directly to obtain line map, use getLineMap function instead.
|
||||
/* @internal */ lineMap: number[];
|
||||
/* @internal */ classifiableNames?: Map<string>;
|
||||
/* @internal */ classifiableNames?: UnderscoreEscapedMap<__String>;
|
||||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
@@ -2463,7 +2463,7 @@ namespace ts {
|
||||
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
|
||||
/* @internal */ dropDiagnosticsProducingTypeChecker(): void;
|
||||
|
||||
/* @internal */ getClassifiableNames(): Map<string>;
|
||||
/* @internal */ getClassifiableNames(): UnderscoreEscapedMap<__String>;
|
||||
|
||||
/* @internal */ getNodeCount(): number;
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
@@ -2937,7 +2937,7 @@ namespace ts {
|
||||
|
||||
export interface Symbol {
|
||||
flags: SymbolFlags; // Symbol flags
|
||||
name: string; // Name of symbol
|
||||
name: __String; // Name of symbol
|
||||
declarations?: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration?: Declaration; // First value declaration of the symbol
|
||||
members?: SymbolTable; // Class, interface or literal instance members
|
||||
@@ -3005,7 +3005,51 @@ namespace ts {
|
||||
isRestParameter?: boolean;
|
||||
}
|
||||
|
||||
export type SymbolTable = Map<Symbol>;
|
||||
export const enum InternalSymbolName {
|
||||
Call = "__call", // Call signatures
|
||||
Constructor = "__constructor", // Constructor implementations
|
||||
New = "__new", // Constructor signatures
|
||||
Index = "__index", // Index signatures
|
||||
ExportStar = "__export", // Module export * declarations
|
||||
Global = "__global", // Global self-reference
|
||||
Missing = "__missing", // Indicates missing symbol
|
||||
Type = "__type", // Anonymous type literal symbol
|
||||
Object = "__object", // Anonymous object literal declaration
|
||||
JSXAttributes = "__jsxAttributes", // Anonymous JSX attributes object literal declaration
|
||||
Class = "__class", // Unnamed class expression
|
||||
Function = "__function", // Unnamed function expression
|
||||
Computed = "__computed", // Computed property name declaration with dynamic name
|
||||
Resolving = "__resolving__", // Indicator symbol used to mark partially resolved type aliases
|
||||
ExportEquals = "export=", // Export assignment symbol
|
||||
Default = "default", // Default export symbol (technically not wholly internal, but included here for usability)
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a string whose leading underscore have been escaped by adding extra leading underscores.
|
||||
* The shape of this brand is rather unique compared to others we've used.
|
||||
* Instead of just an intersection of a string and an object, it is that union-ed
|
||||
* with an intersection of void and an object. This makes it wholly incompatible
|
||||
* with a normal string (which is good, it cannot be misused on assignment or on usage),
|
||||
* while still being comparable with a normal string via === (also good) and castable from a string.
|
||||
*/
|
||||
export type __String = (string & { __escapedIdentifier: void }) | (void & { __escapedIdentifier: void }) | InternalSymbolName;
|
||||
|
||||
/** EscapedStringMap based on ES6 Map interface. */
|
||||
export interface UnderscoreEscapedMap<T> {
|
||||
get(key: __String): T | undefined;
|
||||
has(key: __String): boolean;
|
||||
set(key: __String, value: T): this;
|
||||
delete(key: __String): boolean;
|
||||
clear(): void;
|
||||
forEach(action: (value: T, key: __String) => void): void;
|
||||
readonly size: number;
|
||||
keys(): Iterator<__String>;
|
||||
values(): Iterator<T>;
|
||||
entries(): Iterator<[__String, T]>;
|
||||
}
|
||||
|
||||
/** SymbolTable based on ES6 Map interface. */
|
||||
export type SymbolTable = UnderscoreEscapedMap<Symbol>;
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
|
||||
+73
-19
@@ -351,8 +351,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
|
||||
export function escapeLeadingUnderscores(identifier: string): __String {
|
||||
return (identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier) as __String;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param identifier The identifier to escape
|
||||
*/
|
||||
export function escapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
|
||||
return escapeLeadingUnderscores(identifier) as string;
|
||||
}
|
||||
|
||||
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
|
||||
@@ -467,16 +475,16 @@ namespace ts {
|
||||
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
|
||||
}
|
||||
|
||||
export function getTextOfPropertyName(name: PropertyName): string {
|
||||
export function getTextOfPropertyName(name: PropertyName): __String {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (<Identifier>name).text;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return (<LiteralExpression>name).text;
|
||||
return escapeLeadingUnderscores((<LiteralExpression>name).text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression)) {
|
||||
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
|
||||
return escapeLeadingUnderscores((<LiteralExpression>(<ComputedPropertyName>name).expression).text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,11 +494,11 @@ namespace ts {
|
||||
export function entityNameToString(name: EntityNameOrEntityNameExpression): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return getFullWidth(name) === 0 ? unescapeIdentifier((<Identifier>name).text) : getTextOfNode(name);
|
||||
return getFullWidth(name) === 0 ? unescapeLeadingUnderscores(name.text) : getTextOfNode(name);
|
||||
case SyntaxKind.QualifiedName:
|
||||
return entityNameToString((<QualifiedName>name).left) + "." + entityNameToString((<QualifiedName>name).right);
|
||||
return entityNameToString(name.left) + "." + entityNameToString(name.right);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return entityNameToString((<PropertyAccessEntityNameExpression>name).expression) + "." + entityNameToString((<PropertyAccessEntityNameExpression>name).name);
|
||||
return entityNameToString(name.expression) + "." + entityNameToString(name.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1959,26 +1967,59 @@ namespace ts {
|
||||
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
|
||||
}
|
||||
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName | ParameterDeclaration): string {
|
||||
if (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral || name.kind === SyntaxKind.Parameter) {
|
||||
return (<Identifier | LiteralExpression>name).text;
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name.text;
|
||||
}
|
||||
if (name.kind === SyntaxKind.StringLiteral || name.kind === SyntaxKind.NumericLiteral) {
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
}
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>name).expression;
|
||||
const nameExpression = name.expression;
|
||||
if (isWellKnownSymbolSyntactically(nameExpression)) {
|
||||
const rightHandSideName = (<PropertyAccessExpression>nameExpression).name.text;
|
||||
return getPropertyNameForKnownSymbolName(rightHandSideName);
|
||||
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores(rightHandSideName));
|
||||
}
|
||||
else if (nameExpression.kind === SyntaxKind.StringLiteral || nameExpression.kind === SyntaxKind.NumericLiteral) {
|
||||
return (<LiteralExpression>nameExpression).text;
|
||||
return escapeLeadingUnderscores((<LiteralExpression>nameExpression).text);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getPropertyNameForKnownSymbolName(symbolName: string): string {
|
||||
return "__@" + symbolName;
|
||||
export function getTextOfIdentifierOrLiteral(node: Identifier | LiteralLikeNode) {
|
||||
if (node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
return unescapeLeadingUnderscores((node as Identifier).text);
|
||||
}
|
||||
if (node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return (node as LiteralLikeNode).text;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getEscapedTextOfIdentifierOrLiteral(node: Identifier | LiteralLikeNode) {
|
||||
if (node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
return (node as Identifier).text;
|
||||
}
|
||||
if (node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return escapeLeadingUnderscores((node as LiteralLikeNode).text);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getPropertyNameForKnownSymbolName(symbolName: string): __String {
|
||||
return "__@" + symbolName as __String;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2344,8 +2385,10 @@ namespace ts {
|
||||
return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
}
|
||||
|
||||
export function isIntrinsicJsxName(name: string) {
|
||||
const ch = name.substr(0, 1);
|
||||
export function isIntrinsicJsxName(name: __String | string) {
|
||||
// An escaped identifier had a leading underscore prior to being escaped, which would return true
|
||||
// The escape adds an extra underscore which does not change the result
|
||||
const ch = (name as string).substr(0, 1);
|
||||
return ch.toLowerCase() === ch;
|
||||
}
|
||||
|
||||
@@ -3974,8 +4017,19 @@ namespace ts {
|
||||
* @param identifier The escaped identifier text.
|
||||
* @returns The unescaped identifier text.
|
||||
*/
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
export function unescapeLeadingUnderscores(identifier: __String): string {
|
||||
const id = identifier as string;
|
||||
return id.length >= 3 && id.charCodeAt(0) === CharacterCodes._ && id.charCodeAt(1) === CharacterCodes._ && id.charCodeAt(2) === CharacterCodes._ ? id.substr(1) : id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove extra underscore from escaped identifier text content.
|
||||
* @deprecated
|
||||
* @param identifier The escaped identifier text.
|
||||
* @returns The unescaped identifier text.
|
||||
*/
|
||||
export function unescapeIdentifier(id: string): string {
|
||||
return unescapeLeadingUnderscores(id as __String);
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration): DeclarationName | undefined {
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: Map<string>, span: TextSpan): ClassifiedSpan[] {
|
||||
export function getSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: UnderscoreEscapedMap<__String>, span: TextSpan): ClassifiedSpan[] {
|
||||
return convertClassifications(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span));
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getEncodedSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: Map<string>, span: TextSpan): Classifications {
|
||||
export function getEncodedSemanticClassifications(typeChecker: TypeChecker, cancellationToken: CancellationToken, sourceFile: SourceFile, classifiableNames: UnderscoreEscapedMap<__String>, span: TextSpan): Classifications {
|
||||
const result: number[] = [];
|
||||
processNode(sourceFile);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace ts.codefix {
|
||||
*/
|
||||
export function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker): Node[] {
|
||||
const classMembers = classDeclaration.symbol.members;
|
||||
const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.getName()));
|
||||
const missingMembers = possiblyMissingSymbols.filter(symbol => !classMembers.has(symbol.name));
|
||||
|
||||
let newNodes: Node[] = [];
|
||||
for (const symbol of missingMembers) {
|
||||
@@ -205,7 +205,7 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
|
||||
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.getName());
|
||||
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.getUnescapedName());
|
||||
|
||||
const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*addAnyType*/ true);
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace ts.codefix {
|
||||
else if (isJsxOpeningLikeElement(token.parent) && token.parent.tagName === token) {
|
||||
// The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`.
|
||||
symbol = checker.getAliasedSymbol(checker.resolveNameAtLocation(token, checker.getJsxNamespace(), SymbolFlags.Value));
|
||||
symbolName = symbol.name;
|
||||
symbolName = symbol.getUnescapedName();
|
||||
}
|
||||
else {
|
||||
Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
|
||||
|
||||
+15
-13
@@ -88,10 +88,11 @@ namespace ts.Completions {
|
||||
if (pos === position) {
|
||||
return;
|
||||
}
|
||||
const realName = unescapeLeadingUnderscores(name);
|
||||
|
||||
if (!uniqueNames.get(name)) {
|
||||
uniqueNames.set(name, name);
|
||||
const displayName = getCompletionEntryDisplayName(unescapeIdentifier(name), target, /*performCharacterChecks*/ true);
|
||||
if (!uniqueNames.get(realName)) {
|
||||
uniqueNames.set(realName, realName);
|
||||
const displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true);
|
||||
if (displayName) {
|
||||
const entry = {
|
||||
name: displayName,
|
||||
@@ -139,7 +140,7 @@ namespace ts.Completions {
|
||||
for (const symbol of symbols) {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target);
|
||||
if (entry) {
|
||||
const id = escapeIdentifier(entry.name);
|
||||
const id = entry.name;
|
||||
if (!uniqueNames.get(id)) {
|
||||
entries.push(entry);
|
||||
uniqueNames.set(id, id);
|
||||
@@ -613,7 +614,7 @@ namespace ts.Completions {
|
||||
if (symbol && symbol.flags & SymbolFlags.HasExports) {
|
||||
// Extract module or enum members
|
||||
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
|
||||
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name);
|
||||
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.getUnescapedName());
|
||||
const isValidTypeAccess = (symbol: Symbol) => symbolCanbeReferencedAtTypeLocation(symbol);
|
||||
const isValidAccess = isRhsOfImportDeclaration ?
|
||||
// Any kind is allowed when dotting off namespace in internal import equals declaration
|
||||
@@ -637,7 +638,7 @@ namespace ts.Completions {
|
||||
if (type) {
|
||||
// Filter private properties
|
||||
for (const symbol of type.getApparentProperties()) {
|
||||
if (typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name)) {
|
||||
if (typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.getUnescapedName())) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
@@ -1446,7 +1447,7 @@ namespace ts.Completions {
|
||||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] {
|
||||
const existingImportsOrExports = createMap<boolean>();
|
||||
const existingImportsOrExports = createUnderscoreEscapedMap<boolean>();
|
||||
|
||||
for (const element of namedImportsOrExports) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
@@ -1476,7 +1477,7 @@ namespace ts.Completions {
|
||||
return contextualMemberSymbols;
|
||||
}
|
||||
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
const existingMemberNames = createUnderscoreEscapedMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
if (m.kind !== SyntaxKind.PropertyAssignment &&
|
||||
@@ -1493,7 +1494,7 @@ namespace ts.Completions {
|
||||
continue;
|
||||
}
|
||||
|
||||
let existingName: string;
|
||||
let existingName: __String;
|
||||
|
||||
if (m.kind === SyntaxKind.BindingElement && (<BindingElement>m).propertyName) {
|
||||
// include only identifiers in completion list
|
||||
@@ -1502,10 +1503,11 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO(jfreeman): Account for computed property name
|
||||
// TODO: Account for computed property name
|
||||
// NOTE: if one only performs this step when m.name is an identifier,
|
||||
// things like '__proto__' are not filtered out.
|
||||
existingName = (getNameOfDeclaration(m) as Identifier).text;
|
||||
const name = getNameOfDeclaration(m);
|
||||
existingName = getEscapedTextOfIdentifierOrLiteral(name as (Identifier | LiteralExpression));
|
||||
}
|
||||
|
||||
existingMemberNames.set(existingName, true);
|
||||
@@ -1520,7 +1522,7 @@ namespace ts.Completions {
|
||||
* @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags
|
||||
*/
|
||||
function filterClassMembersList(baseSymbols: Symbol[], implementingTypeSymbols: Symbol[], existingMembers: ClassElement[], currentClassElementModifierFlags: ModifierFlags): Symbol[] {
|
||||
const existingMemberNames = createMap<boolean>();
|
||||
const existingMemberNames = createUnderscoreEscapedMap<boolean>();
|
||||
for (const m of existingMembers) {
|
||||
// Ignore omitted expressions for missing members
|
||||
if (m.kind !== SyntaxKind.PropertyDeclaration &&
|
||||
@@ -1573,7 +1575,7 @@ namespace ts.Completions {
|
||||
* do not occur at the current position and have not otherwise been typed.
|
||||
*/
|
||||
function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>): Symbol[] {
|
||||
const seenNames = createMap<boolean>();
|
||||
const seenNames = createUnderscoreEscapedMap<boolean>();
|
||||
for (const attr of attributes) {
|
||||
// If this is the current item we are editing right now, do not filter it out
|
||||
if (isCurrentlyEditingNode(attr)) {
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace ts.DocumentHighlights {
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
if (!statement.label || isLabeledBy(node, statement.label.text)) {
|
||||
if (!statement.label || isLabeledBy(node, unescapeLeadingUnderscores(statement.label.text))) {
|
||||
return node;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
case "label": {
|
||||
const { node } = def;
|
||||
return { node, name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] };
|
||||
return { node, name: unescapeLeadingUnderscores(node.text), kind: ScriptElementKind.label, displayParts: [displayPart(unescapeLeadingUnderscores(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), (<Identifier>node).text);
|
||||
const labelDefinition = getTargetLabel((<BreakOrContinueStatement>node.parent), unescapeLeadingUnderscores((<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);
|
||||
@@ -432,7 +432,7 @@ namespace ts.FindAllReferences.Core {
|
||||
readonly location: Node;
|
||||
readonly symbol: Symbol;
|
||||
readonly text: string;
|
||||
readonly escapedText: string;
|
||||
readonly escapedText: __String;
|
||||
/** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */
|
||||
readonly parents: Symbol[] | undefined;
|
||||
|
||||
@@ -494,7 +494,7 @@ namespace ts.FindAllReferences.Core {
|
||||
createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search {
|
||||
// Note: if this is an external module symbol, the name doesn't include quotes.
|
||||
const { text = stripQuotes(getDeclaredName(this.checker, symbol, location)), allSearchSymbols = undefined } = searchOptions;
|
||||
const escapedText = escapeIdentifier(text);
|
||||
const escapedText = escapeLeadingUnderscores(text);
|
||||
const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
|
||||
return {
|
||||
location, symbol, comingFrom, text, escapedText, parents,
|
||||
@@ -604,7 +604,7 @@ namespace ts.FindAllReferences.Core {
|
||||
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
|
||||
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
|
||||
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
|
||||
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
|
||||
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, unescapeLeadingUnderscores((<Identifier>bindingElement.name).text));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -716,7 +716,7 @@ namespace ts.FindAllReferences.Core {
|
||||
function getLabelReferencesInNode(container: Node, targetLabel: Identifier): SymbolAndEntries[] {
|
||||
const references: Entry[] = [];
|
||||
const sourceFile = container.getSourceFile();
|
||||
const labelName = targetLabel.text;
|
||||
const labelName = unescapeLeadingUnderscores(targetLabel.text);
|
||||
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container);
|
||||
for (const position of possiblePositions) {
|
||||
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
@@ -733,7 +733,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 unescapeIdentifier((node as Identifier).text).length === searchSymbolName.length;
|
||||
return unescapeLeadingUnderscores((node as Identifier).text).length === searchSymbolName.length;
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
|
||||
@@ -977,7 +977,7 @@ namespace ts.FindAllReferences.Core {
|
||||
* Reference the constructor and all calls to `new this()`.
|
||||
*/
|
||||
function findOwnConstructorReferences(classSymbol: Symbol, sourceFile: SourceFile, addNode: (node: Node) => void): void {
|
||||
for (const decl of classSymbol.members.get("__constructor").declarations) {
|
||||
for (const decl of classSymbol.members.get(InternalSymbolName.Constructor).declarations) {
|
||||
const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)!;
|
||||
Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword);
|
||||
addNode(ctrKeyword);
|
||||
@@ -1001,7 +1001,7 @@ namespace ts.FindAllReferences.Core {
|
||||
/** Find references to `super` in the constructor of an extending class. */
|
||||
function findSuperConstructorAccesses(cls: ClassLikeDeclaration, addNode: (node: Node) => void): void {
|
||||
const symbol = cls.symbol;
|
||||
const ctr = symbol.members.get("__constructor");
|
||||
const ctr = symbol.members.get(InternalSymbolName.Constructor);
|
||||
if (!ctr) {
|
||||
return;
|
||||
}
|
||||
@@ -1414,7 +1414,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members
|
||||
if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter &&
|
||||
isParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration)) {
|
||||
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
|
||||
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.getUnescapedName()));
|
||||
}
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
@@ -1433,7 +1433,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap<Symbol>(), checker);
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getUnescapedName(), result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1551,7 +1551,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result, /*previousIterationSymbolsCache*/ createMap<Symbol>(), state.checker);
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getUnescapedName(), result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
|
||||
return find(result, search.includes);
|
||||
}
|
||||
|
||||
@@ -1568,7 +1568,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return (<Identifier | LiteralExpression>node.name).text;
|
||||
return getTextOfIdentifierOrLiteral(node.name);
|
||||
}
|
||||
|
||||
/** Gets all symbols for one property. Does not get symbols for every property. */
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace ts.GoToDefinition {
|
||||
|
||||
// Labels
|
||||
if (isJumpStatementTarget(node)) {
|
||||
const labelName = (<Identifier>node).text;
|
||||
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
|
||||
const labelName = unescapeLeadingUnderscores((<Identifier>node).text);
|
||||
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), labelName);
|
||||
return label ? [createDefinitionInfoFromName(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -595,9 +595,9 @@ namespace ts.FindAllReferences {
|
||||
return isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol, exportKind } : undefined;
|
||||
}
|
||||
|
||||
function symbolName(symbol: Symbol): string | undefined {
|
||||
function symbolName(symbol: Symbol): __String | undefined {
|
||||
if (symbol.name !== "default") {
|
||||
return symbol.name;
|
||||
return symbol.getName();
|
||||
}
|
||||
|
||||
return forEach(symbol.declarations, decl => {
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace ts.JsDoc {
|
||||
if (tagsForDoc) {
|
||||
tags.push(...tagsForDoc.filter(tag => tag.kind === SyntaxKind.JSDocTag).map(jsDocTag => {
|
||||
return {
|
||||
name: jsDocTag.tagName.text,
|
||||
name: unescapeLeadingUnderscores(jsDocTag.tagName.text),
|
||||
text: jsDocTag.comment
|
||||
}; }));
|
||||
}
|
||||
@@ -133,7 +133,7 @@ namespace ts.JsDoc {
|
||||
}
|
||||
|
||||
export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] {
|
||||
const nameThusFar = tag.name.text;
|
||||
const nameThusFar = unescapeLeadingUnderscores(tag.name.text);
|
||||
const jsdoc = tag.parent;
|
||||
const fn = jsdoc.parent;
|
||||
if (!ts.isFunctionLike(fn)) return [];
|
||||
@@ -141,7 +141,7 @@ namespace ts.JsDoc {
|
||||
return mapDefined(fn.parameters, param => {
|
||||
if (!isIdentifier(param.name)) return undefined;
|
||||
|
||||
const name = param.name.text;
|
||||
const name = unescapeLeadingUnderscores(param.name.text);
|
||||
if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && t.name.text === name)
|
||||
|| nameThusFar !== undefined && !startsWith(name, nameThusFar)) {
|
||||
return undefined;
|
||||
|
||||
@@ -83,24 +83,11 @@ namespace ts.NavigateTo {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getTextOfIdentifierOrLiteral(node: Node) {
|
||||
if (node) {
|
||||
if (node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return (<Identifier | LiteralExpression>node).text;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryAddSingleDeclarationName(declaration: Declaration, containers: string[]) {
|
||||
if (declaration) {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
if (name) {
|
||||
const text = getTextOfIdentifierOrLiteral(name);
|
||||
const text = getTextOfIdentifierOrLiteral(name as (Identifier | LiteralExpression));
|
||||
if (text !== undefined) {
|
||||
containers.unshift(text);
|
||||
}
|
||||
@@ -121,7 +108,7 @@ namespace ts.NavigateTo {
|
||||
//
|
||||
// [X.Y.Z]() { }
|
||||
function tryAddComputedPropertyName(expression: Expression, containers: string[], includeLastPortion: boolean): boolean {
|
||||
const text = getTextOfIdentifierOrLiteral(expression);
|
||||
const text = getTextOfIdentifierOrLiteral(expression as LiteralExpression);
|
||||
if (text !== undefined) {
|
||||
if (includeLastPortion) {
|
||||
containers.unshift(text);
|
||||
@@ -132,7 +119,7 @@ namespace ts.NavigateTo {
|
||||
if (expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const propertyAccess = <PropertyAccessExpression>expression;
|
||||
if (includeLastPortion) {
|
||||
containers.unshift(propertyAccess.name.text);
|
||||
containers.unshift(unescapeLeadingUnderscores(propertyAccess.name.text));
|
||||
}
|
||||
|
||||
return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true);
|
||||
@@ -204,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 ? (<Identifier>containerName).text : "",
|
||||
containerName: containerName ? unescapeLeadingUnderscores((<Identifier>containerName).text) : "",
|
||||
containerKind: containerName ? getNodeKind(container) : ScriptElementKind.unknown
|
||||
};
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ namespace ts.NavigationBar {
|
||||
|
||||
const declName = getNameOfDeclaration(<Declaration>node);
|
||||
if (declName) {
|
||||
return getPropertyNameForPropertyNameNode(declName);
|
||||
return unescapeLeadingUnderscores(getPropertyNameForPropertyNameNode(declName));
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@@ -442,7 +442,7 @@ namespace ts.NavigationBar {
|
||||
|
||||
function getJSDocTypedefTagName(node: JSDocTypedefTag): string {
|
||||
if (node.name) {
|
||||
return node.name.text;
|
||||
return unescapeLeadingUnderscores(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 (<Identifier>nameIdentifier).text;
|
||||
return unescapeLeadingUnderscores((<Identifier>nameIdentifier).text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,12 +580,12 @@ namespace ts.NavigationBar {
|
||||
// Otherwise, we need to aggregate each identifier to build up the qualified name.
|
||||
const result: string[] = [];
|
||||
|
||||
result.push(moduleDeclaration.name.text);
|
||||
result.push(getTextOfIdentifierOrLiteral(moduleDeclaration.name));
|
||||
|
||||
while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
moduleDeclaration = <ModuleDeclaration>moduleDeclaration.body;
|
||||
|
||||
result.push(moduleDeclaration.name.text);
|
||||
result.push(getTextOfIdentifierOrLiteral(moduleDeclaration.name));
|
||||
}
|
||||
|
||||
return result.join(".");
|
||||
|
||||
@@ -244,7 +244,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(sym.name));
|
||||
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(unescapeLeadingUnderscores(sym.name)));
|
||||
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
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace ts.refactor {
|
||||
deleteNode(nodeToDelete);
|
||||
|
||||
if (!assignmentBinaryExpression.right) {
|
||||
return createProperty([], modifiers, symbol.name, /*questionToken*/ undefined,
|
||||
return createProperty([], modifiers, symbol.getUnescapedName(), /*questionToken*/ undefined,
|
||||
/*type*/ undefined, /*initializer*/ undefined);
|
||||
}
|
||||
|
||||
|
||||
+17
-26
@@ -304,7 +304,7 @@ namespace ts {
|
||||
|
||||
class SymbolObject implements Symbol {
|
||||
flags: SymbolFlags;
|
||||
name: string;
|
||||
name: __String;
|
||||
declarations?: Declaration[];
|
||||
|
||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||
@@ -315,7 +315,7 @@ namespace ts {
|
||||
// symbol has no JSDoc tags, then the empty array will be returned.
|
||||
tags?: JSDocTagInfo[];
|
||||
|
||||
constructor(flags: SymbolFlags, name: string) {
|
||||
constructor(flags: SymbolFlags, name: __String) {
|
||||
this.flags = flags;
|
||||
this.name = name;
|
||||
}
|
||||
@@ -324,10 +324,14 @@ namespace ts {
|
||||
return this.flags;
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
getName(): __String {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
getUnescapedName(): string {
|
||||
return unescapeLeadingUnderscores(this.name);
|
||||
}
|
||||
|
||||
getDeclarations(): Declaration[] | undefined {
|
||||
return this.declarations;
|
||||
}
|
||||
@@ -360,7 +364,7 @@ namespace ts {
|
||||
|
||||
class IdentifierObject extends TokenOrIdentifierObject implements Identifier {
|
||||
public kind: SyntaxKind.Identifier;
|
||||
public text: string;
|
||||
public text: __String;
|
||||
_primaryExpressionBrand: any;
|
||||
_memberExpressionBrand: any;
|
||||
_leftHandSideExpressionBrand: any;
|
||||
@@ -509,7 +513,7 @@ namespace ts {
|
||||
public languageVersion: ScriptTarget;
|
||||
public languageVariant: LanguageVariant;
|
||||
public identifiers: Map<string>;
|
||||
public nameTable: Map<number>;
|
||||
public nameTable: UnderscoreEscapedMap<number>;
|
||||
public resolvedModules: Map<ResolvedModuleFull>;
|
||||
public resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
public imports: StringLiteral[];
|
||||
@@ -589,7 +593,7 @@ namespace ts {
|
||||
function getDeclarationName(declaration: Declaration) {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
if (name) {
|
||||
const result = getTextOfIdentifierOrLiteral(name);
|
||||
const result = getTextOfIdentifierOrLiteral(name as (Identifier | LiteralExpression));
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
@@ -597,23 +601,10 @@ namespace ts {
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const expr = (<ComputedPropertyName>name).expression;
|
||||
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
return (<PropertyAccessExpression>expr).name.text;
|
||||
return unescapeLeadingUnderscores((<PropertyAccessExpression>expr).name.text);
|
||||
}
|
||||
|
||||
return getTextOfIdentifierOrLiteral(expr);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTextOfIdentifierOrLiteral(node: Node) {
|
||||
if (node) {
|
||||
if (node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.NumericLiteral) {
|
||||
|
||||
return (<Identifier | LiteralExpression>node).text;
|
||||
return getTextOfIdentifierOrLiteral(expr as (Identifier | LiteralExpression));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2082,7 +2073,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
/** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */
|
||||
export function getNameTable(sourceFile: SourceFile): Map<number> {
|
||||
export function getNameTable(sourceFile: SourceFile): UnderscoreEscapedMap<number> {
|
||||
if (!sourceFile.nameTable) {
|
||||
initializeNameTable(sourceFile);
|
||||
}
|
||||
@@ -2091,7 +2082,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function initializeNameTable(sourceFile: SourceFile): void {
|
||||
const nameTable = createMap<number>();
|
||||
const nameTable = createUnderscoreEscapedMap<number>();
|
||||
|
||||
walk(sourceFile);
|
||||
sourceFile.nameTable = nameTable;
|
||||
@@ -2111,7 +2102,7 @@ namespace ts {
|
||||
node.parent.kind === SyntaxKind.ExternalModuleReference ||
|
||||
isArgumentOfElementAccessExpression(node) ||
|
||||
isLiteralComputedPropertyDeclarationName(node)) {
|
||||
setNameTable((<LiteralExpression>node).text, node);
|
||||
setNameTable(getEscapedTextOfIdentifierOrLiteral((<LiteralExpression>node)), node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -2124,7 +2115,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function setNameTable(text: string, node: ts.Node): void {
|
||||
function setNameTable(text: __String, node: ts.Node): void {
|
||||
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
|
||||
}
|
||||
}
|
||||
@@ -2167,7 +2158,7 @@ namespace ts {
|
||||
export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] {
|
||||
const objectLiteral = <ObjectLiteralExpression | JsxAttributes>node.parent;
|
||||
const contextualType = typeChecker.getContextualType(objectLiteral);
|
||||
const name = getTextOfPropertyName(node.name);
|
||||
const name = unescapeLeadingUnderscores(getTextOfPropertyName(node.name));
|
||||
if (name && contextualType) {
|
||||
const result: Symbol[] = [];
|
||||
const symbol = contextualType.getProperty(name);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace ts.SignatureHelp {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
const nameToDeclarations = sourceFile.getNamedDeclarations();
|
||||
const declarations = nameToDeclarations.get(name.text);
|
||||
const declarations = nameToDeclarations.get(unescapeLeadingUnderscores(name.text));
|
||||
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
@@ -416,7 +416,7 @@ namespace ts.SignatureHelp {
|
||||
typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation));
|
||||
|
||||
return {
|
||||
name: parameter.name,
|
||||
name: parameter.getUnescapedName(),
|
||||
documentation: parameter.getDocumentationComment(),
|
||||
displayParts,
|
||||
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration)
|
||||
@@ -428,7 +428,7 @@ namespace ts.SignatureHelp {
|
||||
typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation));
|
||||
|
||||
return {
|
||||
name: typeParameter.symbol.name,
|
||||
name: typeParameter.symbol.getUnescapedName(),
|
||||
documentation: emptyArray,
|
||||
displayParts,
|
||||
isOptional: false
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace ts {
|
||||
|
||||
export interface Symbol {
|
||||
getFlags(): SymbolFlags;
|
||||
getName(): string;
|
||||
getName(): __String;
|
||||
getUnescapedName(): string;
|
||||
getDeclarations(): Declaration[] | undefined;
|
||||
getDocumentationComment(): SymbolDisplayPart[];
|
||||
getJsDocTags(): JSDocTagInfo[];
|
||||
@@ -56,7 +57,7 @@ namespace ts {
|
||||
export interface SourceFile {
|
||||
/* @internal */ version: string;
|
||||
/* @internal */ scriptSnapshot: IScriptSnapshot;
|
||||
/* @internal */ nameTable: Map<number>;
|
||||
/* @internal */ nameTable: UnderscoreEscapedMap<number>;
|
||||
|
||||
/* @internal */ getNamedDeclarations(): Map<Declaration[]>;
|
||||
|
||||
|
||||
@@ -1092,7 +1092,7 @@ namespace ts {
|
||||
/** True if the symbol is for an external module, as opposed to a namespace. */
|
||||
export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
Debug.assert(!!(moduleSymbol.flags & SymbolFlags.Module));
|
||||
return moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
return moduleSymbol.getUnescapedName().charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
/** Returns `true` the first time it encounters a node and `false` afterwards. */
|
||||
@@ -1272,7 +1272,7 @@ namespace ts {
|
||||
// If this is an export or import specifier it could have been renamed using the 'as' syntax.
|
||||
// If so we want to search for whatever is under the cursor.
|
||||
if (isImportOrExportSpecifierName(location) || isStringOrNumericLiteral(location) && location.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return location.text;
|
||||
return getTextOfIdentifierOrLiteral(location);
|
||||
}
|
||||
|
||||
// Try to get the local symbol if we're dealing with an 'export default'
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//// [doubleUnderscoreEnumEmit.ts]
|
||||
enum Foo {
|
||||
"__a" = 1,
|
||||
"(Anonymous function)" = 2,
|
||||
"(Anonymous class)" = 4,
|
||||
"__call" = 10
|
||||
}
|
||||
namespace Foo {
|
||||
export function ___call(): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
function Bar() {
|
||||
return "no";
|
||||
}
|
||||
namespace Bar {
|
||||
export function __call(x: number): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
//// [doubleUnderscoreEnumEmit.js]
|
||||
var Foo;
|
||||
(function (Foo) {
|
||||
Foo[Foo["__a"] = 1] = "__a";
|
||||
Foo[Foo["(Anonymous function)"] = 2] = "(Anonymous function)";
|
||||
Foo[Foo["(Anonymous class)"] = 4] = "(Anonymous class)";
|
||||
Foo[Foo["__call"] = 10] = "__call";
|
||||
})(Foo || (Foo = {}));
|
||||
(function (Foo) {
|
||||
function ___call() {
|
||||
return 5;
|
||||
}
|
||||
Foo.___call = ___call;
|
||||
})(Foo || (Foo = {}));
|
||||
function Bar() {
|
||||
return "no";
|
||||
}
|
||||
(function (Bar) {
|
||||
function __call(x) {
|
||||
return 5;
|
||||
}
|
||||
Bar.__call = __call;
|
||||
})(Bar || (Bar = {}));
|
||||
@@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreEnumEmit.ts ===
|
||||
enum Foo {
|
||||
>Foo : Symbol(Foo, Decl(doubleUnderscoreEnumEmit.ts, 0, 0), Decl(doubleUnderscoreEnumEmit.ts, 5, 1))
|
||||
|
||||
"__a" = 1,
|
||||
"(Anonymous function)" = 2,
|
||||
"(Anonymous class)" = 4,
|
||||
"__call" = 10
|
||||
}
|
||||
namespace Foo {
|
||||
>Foo : Symbol(Foo, Decl(doubleUnderscoreEnumEmit.ts, 0, 0), Decl(doubleUnderscoreEnumEmit.ts, 5, 1))
|
||||
|
||||
export function ___call(): number {
|
||||
>___call : Symbol(___call, Decl(doubleUnderscoreEnumEmit.ts, 6, 15))
|
||||
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
function Bar() {
|
||||
>Bar : Symbol(Bar, Decl(doubleUnderscoreEnumEmit.ts, 10, 1), Decl(doubleUnderscoreEnumEmit.ts, 13, 1))
|
||||
|
||||
return "no";
|
||||
}
|
||||
namespace Bar {
|
||||
>Bar : Symbol(Bar, Decl(doubleUnderscoreEnumEmit.ts, 10, 1), Decl(doubleUnderscoreEnumEmit.ts, 13, 1))
|
||||
|
||||
export function __call(x: number): number {
|
||||
>__call : Symbol(__call, Decl(doubleUnderscoreEnumEmit.ts, 14, 15))
|
||||
>x : Symbol(x, Decl(doubleUnderscoreEnumEmit.ts, 15, 27))
|
||||
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreEnumEmit.ts ===
|
||||
enum Foo {
|
||||
>Foo : Foo
|
||||
|
||||
"__a" = 1,
|
||||
>1 : 1
|
||||
|
||||
"(Anonymous function)" = 2,
|
||||
>2 : 2
|
||||
|
||||
"(Anonymous class)" = 4,
|
||||
>4 : 4
|
||||
|
||||
"__call" = 10
|
||||
>10 : 10
|
||||
}
|
||||
namespace Foo {
|
||||
>Foo : typeof Foo
|
||||
|
||||
export function ___call(): number {
|
||||
>___call : () => number
|
||||
|
||||
return 5;
|
||||
>5 : 5
|
||||
}
|
||||
}
|
||||
function Bar() {
|
||||
>Bar : typeof Bar
|
||||
|
||||
return "no";
|
||||
>"no" : "no"
|
||||
}
|
||||
namespace Bar {
|
||||
>Bar : typeof Bar
|
||||
|
||||
export function __call(x: number): number {
|
||||
>__call : (x: number) => number
|
||||
>x : number
|
||||
|
||||
return 5;
|
||||
>5 : 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
tests/cases/compiler/index.tsx(2,1): error TS2308: Module "./b" has already exported a member named '__foo'. Consider explicitly re-exporting to resolve the ambiguity.
|
||||
|
||||
|
||||
==== tests/cases/compiler/index.tsx (1 errors) ====
|
||||
export * from "./b";
|
||||
export * from "./c";
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2308: Module "./b" has already exported a member named '__foo'. Consider explicitly re-exporting to resolve the ambiguity.
|
||||
|
||||
==== tests/cases/compiler/b.ts (0 errors) ====
|
||||
export function __foo(): number | void {}
|
||||
|
||||
==== tests/cases/compiler/c.ts (0 errors) ====
|
||||
export function __foo(): string | void {}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//// [tests/cases/compiler/doubleUnderscoreExportStarConflict.ts] ////
|
||||
|
||||
//// [index.tsx]
|
||||
export * from "./b";
|
||||
export * from "./c";
|
||||
|
||||
//// [b.ts]
|
||||
export function __foo(): number | void {}
|
||||
|
||||
//// [c.ts]
|
||||
export function __foo(): string | void {}
|
||||
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function __foo() { }
|
||||
exports.__foo = __foo;
|
||||
//// [c.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function __foo() { }
|
||||
exports.__foo = __foo;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
exports.__esModule = true;
|
||||
__export(require("./b"));
|
||||
__export(require("./c"));
|
||||
@@ -0,0 +1,29 @@
|
||||
//// [doubleUnderscoreLabels.ts]
|
||||
function doThing() {
|
||||
__call: while (true) {
|
||||
aLabel: for (let i = 0; i < 10; i++) {
|
||||
if (i === 3) {
|
||||
break __call;
|
||||
}
|
||||
if (i === 5) {
|
||||
break aLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doThing();
|
||||
|
||||
//// [doubleUnderscoreLabels.js]
|
||||
function doThing() {
|
||||
__call: while (true) {
|
||||
aLabel: for (var i = 0; i < 10; i++) {
|
||||
if (i === 3) {
|
||||
break __call;
|
||||
}
|
||||
if (i === 5) {
|
||||
break aLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doThing();
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreLabels.ts ===
|
||||
function doThing() {
|
||||
>doThing : Symbol(doThing, Decl(doubleUnderscoreLabels.ts, 0, 0))
|
||||
|
||||
__call: while (true) {
|
||||
aLabel: for (let i = 0; i < 10; i++) {
|
||||
>i : Symbol(i, Decl(doubleUnderscoreLabels.ts, 2, 24))
|
||||
>i : Symbol(i, Decl(doubleUnderscoreLabels.ts, 2, 24))
|
||||
>i : Symbol(i, Decl(doubleUnderscoreLabels.ts, 2, 24))
|
||||
|
||||
if (i === 3) {
|
||||
>i : Symbol(i, Decl(doubleUnderscoreLabels.ts, 2, 24))
|
||||
|
||||
break __call;
|
||||
}
|
||||
if (i === 5) {
|
||||
>i : Symbol(i, Decl(doubleUnderscoreLabels.ts, 2, 24))
|
||||
|
||||
break aLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doThing();
|
||||
>doThing : Symbol(doThing, Decl(doubleUnderscoreLabels.ts, 0, 0))
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreLabels.ts ===
|
||||
function doThing() {
|
||||
>doThing : () => void
|
||||
|
||||
__call: while (true) {
|
||||
>__call : any
|
||||
>true : true
|
||||
|
||||
aLabel: for (let i = 0; i < 10; i++) {
|
||||
>aLabel : any
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>i++ : number
|
||||
>i : number
|
||||
|
||||
if (i === 3) {
|
||||
>i === 3 : boolean
|
||||
>i : number
|
||||
>3 : 3
|
||||
|
||||
break __call;
|
||||
>__call : any
|
||||
}
|
||||
if (i === 5) {
|
||||
>i === 5 : boolean
|
||||
>i : number
|
||||
>5 : 5
|
||||
|
||||
break aLabel;
|
||||
>aLabel : any
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doThing();
|
||||
>doThing() : void
|
||||
>doThing : () => void
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
//// [doubleUnderscoreMappedTypes.ts]
|
||||
interface Properties {
|
||||
property1: string;
|
||||
__property2: string;
|
||||
}
|
||||
|
||||
// As expected, I can make an object satisfying this interface
|
||||
const ok: Properties = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
|
||||
// As expected, "__property2" is indeed a key of the type
|
||||
type Keys = keyof Properties;
|
||||
const k: Keys = "__property2"; // ok
|
||||
|
||||
// This should be valid
|
||||
type Property2Type = Properties["__property2"];
|
||||
|
||||
// And should work with partial
|
||||
const partial: Partial<Properties> = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
|
||||
|
||||
//// [doubleUnderscoreMappedTypes.js]
|
||||
// As expected, I can make an object satisfying this interface
|
||||
var ok = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
var k = "__property2"; // ok
|
||||
// And should work with partial
|
||||
var partial = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreMappedTypes.ts ===
|
||||
interface Properties {
|
||||
>Properties : Symbol(Properties, Decl(doubleUnderscoreMappedTypes.ts, 0, 0))
|
||||
|
||||
property1: string;
|
||||
>property1 : Symbol(Properties.property1, Decl(doubleUnderscoreMappedTypes.ts, 0, 22))
|
||||
|
||||
__property2: string;
|
||||
>__property2 : Symbol(Properties.__property2, Decl(doubleUnderscoreMappedTypes.ts, 1, 22))
|
||||
}
|
||||
|
||||
// As expected, I can make an object satisfying this interface
|
||||
const ok: Properties = {
|
||||
>ok : Symbol(ok, Decl(doubleUnderscoreMappedTypes.ts, 6, 5))
|
||||
>Properties : Symbol(Properties, Decl(doubleUnderscoreMappedTypes.ts, 0, 0))
|
||||
|
||||
property1: "",
|
||||
>property1 : Symbol(property1, Decl(doubleUnderscoreMappedTypes.ts, 6, 24))
|
||||
|
||||
__property2: ""
|
||||
>__property2 : Symbol(__property2, Decl(doubleUnderscoreMappedTypes.ts, 7, 18))
|
||||
|
||||
};
|
||||
|
||||
// As expected, "__property2" is indeed a key of the type
|
||||
type Keys = keyof Properties;
|
||||
>Keys : Symbol(Keys, Decl(doubleUnderscoreMappedTypes.ts, 9, 2))
|
||||
>Properties : Symbol(Properties, Decl(doubleUnderscoreMappedTypes.ts, 0, 0))
|
||||
|
||||
const k: Keys = "__property2"; // ok
|
||||
>k : Symbol(k, Decl(doubleUnderscoreMappedTypes.ts, 13, 5))
|
||||
>Keys : Symbol(Keys, Decl(doubleUnderscoreMappedTypes.ts, 9, 2))
|
||||
|
||||
// This should be valid
|
||||
type Property2Type = Properties["__property2"];
|
||||
>Property2Type : Symbol(Property2Type, Decl(doubleUnderscoreMappedTypes.ts, 13, 30))
|
||||
>Properties : Symbol(Properties, Decl(doubleUnderscoreMappedTypes.ts, 0, 0))
|
||||
|
||||
// And should work with partial
|
||||
const partial: Partial<Properties> = {
|
||||
>partial : Symbol(partial, Decl(doubleUnderscoreMappedTypes.ts, 19, 5))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>Properties : Symbol(Properties, Decl(doubleUnderscoreMappedTypes.ts, 0, 0))
|
||||
|
||||
property1: "",
|
||||
>property1 : Symbol(property1, Decl(doubleUnderscoreMappedTypes.ts, 19, 38))
|
||||
|
||||
__property2: ""
|
||||
>__property2 : Symbol(__property2, Decl(doubleUnderscoreMappedTypes.ts, 20, 18))
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
=== tests/cases/compiler/doubleUnderscoreMappedTypes.ts ===
|
||||
interface Properties {
|
||||
>Properties : Properties
|
||||
|
||||
property1: string;
|
||||
>property1 : string
|
||||
|
||||
__property2: string;
|
||||
>__property2 : string
|
||||
}
|
||||
|
||||
// As expected, I can make an object satisfying this interface
|
||||
const ok: Properties = {
|
||||
>ok : Properties
|
||||
>Properties : Properties
|
||||
>{ property1: "", __property2: ""} : { property1: string; __property2: string; }
|
||||
|
||||
property1: "",
|
||||
>property1 : string
|
||||
>"" : ""
|
||||
|
||||
__property2: ""
|
||||
>__property2 : string
|
||||
>"" : ""
|
||||
|
||||
};
|
||||
|
||||
// As expected, "__property2" is indeed a key of the type
|
||||
type Keys = keyof Properties;
|
||||
>Keys : "property1" | "__property2"
|
||||
>Properties : Properties
|
||||
|
||||
const k: Keys = "__property2"; // ok
|
||||
>k : "property1" | "__property2"
|
||||
>Keys : "property1" | "__property2"
|
||||
>"__property2" : "__property2"
|
||||
|
||||
// This should be valid
|
||||
type Property2Type = Properties["__property2"];
|
||||
>Property2Type : string
|
||||
>Properties : Properties
|
||||
|
||||
// And should work with partial
|
||||
const partial: Partial<Properties> = {
|
||||
>partial : Partial<Properties>
|
||||
>Partial : Partial<T>
|
||||
>Properties : Properties
|
||||
>{ property1: "", __property2: ""} : { property1: string; __property2: string; }
|
||||
|
||||
property1: "",
|
||||
>property1 : string
|
||||
>"" : ""
|
||||
|
||||
__property2: ""
|
||||
>__property2 : string
|
||||
>"" : ""
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//// [index.tsx]
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
__foot: any;
|
||||
}
|
||||
}
|
||||
function __make (params: object): any;
|
||||
}
|
||||
|
||||
|
||||
const thing = <__foot></__foot>;
|
||||
|
||||
export {}
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var thing = __make("__foot", null);
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/compiler/index.tsx ===
|
||||
declare global {
|
||||
>global : Symbol(global, Decl(index.tsx, 0, 0))
|
||||
|
||||
namespace JSX {
|
||||
>JSX : Symbol(JSX, Decl(index.tsx, 0, 16))
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.tsx, 1, 19))
|
||||
|
||||
__foot: any;
|
||||
>__foot : Symbol(IntrinsicElements.__foot, Decl(index.tsx, 2, 37))
|
||||
}
|
||||
}
|
||||
function __make (params: object): any;
|
||||
>__make : Symbol(__make, Decl(index.tsx, 5, 5))
|
||||
>params : Symbol(params, Decl(index.tsx, 6, 21))
|
||||
}
|
||||
|
||||
|
||||
const thing = <__foot></__foot>;
|
||||
>thing : Symbol(thing, Decl(index.tsx, 10, 5))
|
||||
>__foot : Symbol(JSX.IntrinsicElements.__foot, Decl(index.tsx, 2, 37))
|
||||
>__foot : Symbol(JSX.IntrinsicElements.__foot, Decl(index.tsx, 2, 37))
|
||||
|
||||
export {}
|
||||
@@ -0,0 +1,27 @@
|
||||
=== tests/cases/compiler/index.tsx ===
|
||||
declare global {
|
||||
>global : typeof global
|
||||
|
||||
namespace JSX {
|
||||
>JSX : any
|
||||
|
||||
interface IntrinsicElements {
|
||||
>IntrinsicElements : IntrinsicElements
|
||||
|
||||
__foot: any;
|
||||
>__foot : any
|
||||
}
|
||||
}
|
||||
function __make (params: object): any;
|
||||
>__make : (params: object) => any
|
||||
>params : object
|
||||
}
|
||||
|
||||
|
||||
const thing = <__foot></__foot>;
|
||||
>thing : any
|
||||
><__foot></__foot> : any
|
||||
>__foot : any
|
||||
>__foot : any
|
||||
|
||||
export {}
|
||||
@@ -11,7 +11,6 @@ var o = {
|
||||
var b = o["__proto__"];
|
||||
>b : Symbol(b, Decl(escapedReservedCompilerNamedIdentifier.ts, 5, 3))
|
||||
>o : Symbol(o, Decl(escapedReservedCompilerNamedIdentifier.ts, 2, 3))
|
||||
>"__proto__" : Symbol("__proto__", Decl(escapedReservedCompilerNamedIdentifier.ts, 2, 9))
|
||||
|
||||
var o1 = {
|
||||
>o1 : Symbol(o1, Decl(escapedReservedCompilerNamedIdentifier.ts, 6, 3))
|
||||
@@ -23,7 +22,6 @@ var o1 = {
|
||||
var b1 = o1["__proto__"];
|
||||
>b1 : Symbol(b1, Decl(escapedReservedCompilerNamedIdentifier.ts, 9, 3))
|
||||
>o1 : Symbol(o1, Decl(escapedReservedCompilerNamedIdentifier.ts, 6, 3))
|
||||
>"__proto__" : Symbol(__proto__, Decl(escapedReservedCompilerNamedIdentifier.ts, 6, 10))
|
||||
|
||||
// Triple underscores
|
||||
var ___proto__ = 10;
|
||||
@@ -37,7 +35,6 @@ var o2 = {
|
||||
var b2 = o2["___proto__"];
|
||||
>b2 : Symbol(b2, Decl(escapedReservedCompilerNamedIdentifier.ts, 15, 3))
|
||||
>o2 : Symbol(o2, Decl(escapedReservedCompilerNamedIdentifier.ts, 12, 3))
|
||||
>"___proto__" : Symbol("___proto__", Decl(escapedReservedCompilerNamedIdentifier.ts, 12, 10))
|
||||
|
||||
var o3 = {
|
||||
>o3 : Symbol(o3, Decl(escapedReservedCompilerNamedIdentifier.ts, 16, 3))
|
||||
@@ -49,7 +46,6 @@ var o3 = {
|
||||
var b3 = o3["___proto__"];
|
||||
>b3 : Symbol(b3, Decl(escapedReservedCompilerNamedIdentifier.ts, 19, 3))
|
||||
>o3 : Symbol(o3, Decl(escapedReservedCompilerNamedIdentifier.ts, 16, 3))
|
||||
>"___proto__" : Symbol(___proto__, Decl(escapedReservedCompilerNamedIdentifier.ts, 16, 10))
|
||||
|
||||
// One underscore
|
||||
var _proto__ = 10;
|
||||
|
||||
@@ -16,7 +16,7 @@ var b = o["__proto__"];
|
||||
>b : number
|
||||
>o["__proto__"] : number
|
||||
>o : { "__proto__": number; }
|
||||
>"__proto__" : "___proto__"
|
||||
>"__proto__" : "__proto__"
|
||||
|
||||
var o1 = {
|
||||
>o1 : { __proto__: number; }
|
||||
@@ -31,7 +31,7 @@ var b1 = o1["__proto__"];
|
||||
>b1 : number
|
||||
>o1["__proto__"] : number
|
||||
>o1 : { __proto__: number; }
|
||||
>"__proto__" : "___proto__"
|
||||
>"__proto__" : "__proto__"
|
||||
|
||||
// Triple underscores
|
||||
var ___proto__ = 10;
|
||||
@@ -50,7 +50,7 @@ var b2 = o2["___proto__"];
|
||||
>b2 : number
|
||||
>o2["___proto__"] : number
|
||||
>o2 : { "___proto__": number; }
|
||||
>"___proto__" : "____proto__"
|
||||
>"___proto__" : "___proto__"
|
||||
|
||||
var o3 = {
|
||||
>o3 : { ___proto__: number; }
|
||||
@@ -65,7 +65,7 @@ var b3 = o3["___proto__"];
|
||||
>b3 : number
|
||||
>o3["___proto__"] : number
|
||||
>o3 : { ___proto__: number; }
|
||||
>"___proto__" : "____proto__"
|
||||
>"___proto__" : "___proto__"
|
||||
|
||||
// One underscore
|
||||
var _proto__ = 10;
|
||||
|
||||
@@ -17,7 +17,7 @@ WorkspacePrototype['__proto__'] = EntityPrototype;
|
||||
>WorkspacePrototype['__proto__'] = EntityPrototype : any
|
||||
>WorkspacePrototype['__proto__'] : any
|
||||
>WorkspacePrototype : { serialize: () => any; }
|
||||
>'__proto__' : "___proto__"
|
||||
>'__proto__' : "__proto__"
|
||||
>EntityPrototype : any
|
||||
|
||||
var o = {
|
||||
|
||||
@@ -7,7 +7,7 @@ class X {
|
||||
>this['__proto__'] = null : null
|
||||
>this['__proto__'] : any
|
||||
>this : this
|
||||
>'__proto__' : "___proto__"
|
||||
>'__proto__' : "__proto__"
|
||||
>null : null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
enum Foo {
|
||||
"__a" = 1,
|
||||
"(Anonymous function)" = 2,
|
||||
"(Anonymous class)" = 4,
|
||||
"__call" = 10
|
||||
}
|
||||
namespace Foo {
|
||||
export function ___call(): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
function Bar() {
|
||||
return "no";
|
||||
}
|
||||
namespace Bar {
|
||||
export function __call(x: number): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// @module: commonjs
|
||||
// @filename: index.tsx
|
||||
|
||||
export * from "./b";
|
||||
export * from "./c";
|
||||
|
||||
// @filename: b.ts
|
||||
export function __foo(): number | void {}
|
||||
|
||||
// @filename: c.ts
|
||||
export function __foo(): string | void {}
|
||||
@@ -0,0 +1,13 @@
|
||||
function doThing() {
|
||||
__call: while (true) {
|
||||
aLabel: for (let i = 0; i < 10; i++) {
|
||||
if (i === 3) {
|
||||
break __call;
|
||||
}
|
||||
if (i === 5) {
|
||||
break aLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doThing();
|
||||
@@ -0,0 +1,23 @@
|
||||
interface Properties {
|
||||
property1: string;
|
||||
__property2: string;
|
||||
}
|
||||
|
||||
// As expected, I can make an object satisfying this interface
|
||||
const ok: Properties = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
|
||||
// As expected, "__property2" is indeed a key of the type
|
||||
type Keys = keyof Properties;
|
||||
const k: Keys = "__property2"; // ok
|
||||
|
||||
// This should be valid
|
||||
type Property2Type = Properties["__property2"];
|
||||
|
||||
// And should work with partial
|
||||
const partial: Partial<Properties> = {
|
||||
property1: "",
|
||||
__property2: ""
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// @jsx: react
|
||||
// @jsxFactory: __make
|
||||
// @module: commonjs
|
||||
// @filename: index.tsx
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
__foot: any;
|
||||
}
|
||||
}
|
||||
function __make (params: object): any;
|
||||
}
|
||||
|
||||
|
||||
const thing = <__foot></__foot>;
|
||||
|
||||
export {}
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @allowJs: true
|
||||
// @Filename: a.js
|
||||
//// function MyObject(){
|
||||
//// this.__property = 1;
|
||||
//// }
|
||||
//// var instance = new MyObject();
|
||||
//// instance./*1*/
|
||||
|
||||
goTo.marker("1");
|
||||
verify.completionListContains("__property", "(property) MyObject.__property: number");
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @Filename: fileA.ts
|
||||
//// export function [|__foo|]() {
|
||||
//// }
|
||||
////
|
||||
// @Filename: fileB.ts
|
||||
//// import { [|__foo|] as bar } from "./fileA";
|
||||
////
|
||||
//// bar();
|
||||
|
||||
verify.rangesAreRenameLocations();
|
||||
Reference in New Issue
Block a user