mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
committed by
unknown
parent
5d8773aa25
commit
85225c8f29
@@ -32,6 +32,7 @@ module ts {
|
||||
var parent: Node;
|
||||
var container: Declaration;
|
||||
var symbolCount = 0;
|
||||
var lastLocals: Declaration;
|
||||
var Symbol = objectAllocator.getSymbolConstructor();
|
||||
|
||||
if (!file.locals) {
|
||||
@@ -162,6 +163,14 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
// All nodes with locals are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
|
||||
// in the type checker to validate that the local name used for a container is unique.
|
||||
function initializeLocals(node: Declaration) {
|
||||
node.locals = {};
|
||||
if (lastLocals) lastLocals.nextLocals = node;
|
||||
lastLocals = node;
|
||||
}
|
||||
|
||||
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
@@ -198,7 +207,7 @@ module ts {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
}
|
||||
if (symbolKind & SymbolFlags.HasLocals) node.locals = {};
|
||||
if (symbolKind & SymbolFlags.HasLocals) initializeLocals(node);
|
||||
var saveParent = parent;
|
||||
var saveContainer = container;
|
||||
parent = node;
|
||||
@@ -232,7 +241,7 @@ module ts {
|
||||
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) {
|
||||
var symbol = createSymbol(symbolKind, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolKind);
|
||||
if (symbolKind & SymbolFlags.HasLocals) node.locals = {};
|
||||
if (symbolKind & SymbolFlags.HasLocals) initializeLocals(node);
|
||||
var saveParent = parent;
|
||||
var saveContainer = container;
|
||||
parent = node;
|
||||
|
||||
@@ -3795,7 +3795,7 @@ module ts {
|
||||
}
|
||||
return checkUntypedCall(node);
|
||||
}
|
||||
// If FuncExpr’s apparent type(section 3.8.1) is a function type, the call is a typed function call.
|
||||
// If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
|
||||
// TypeScript employs overload resolution in typed function calls in order to support functions
|
||||
// with multiple call signatures.
|
||||
if (!signatures.length) {
|
||||
@@ -3827,7 +3827,7 @@ module ts {
|
||||
return checkUntypedCall(node);
|
||||
}
|
||||
|
||||
// If ConstructExpr’s apparent type(section 3.8.1) is an object type with one or
|
||||
// If ConstructExpr's apparent type(section 3.8.1) is an object type with one or
|
||||
// more construct signatures, the expression is processed in the same manner as a
|
||||
// function call, but using the construct signatures as the initial set of candidate
|
||||
// signatures for overload resolution.The result type of the function call becomes
|
||||
@@ -3848,7 +3848,7 @@ module ts {
|
||||
return checkCall(node, constructSignatures);
|
||||
}
|
||||
|
||||
// If ConstructExpr’s apparent type is an object type with no construct signatures but
|
||||
// If ConstructExpr's apparent type is an object type with no construct signatures but
|
||||
// one or more call signatures, the expression is processed as a function call. A compile-time
|
||||
// error occurs if the result of the function call is not Void. The type of the result of the
|
||||
// operation is Any.
|
||||
@@ -6004,14 +6004,53 @@ module ts {
|
||||
|
||||
// Emitter support
|
||||
|
||||
function getModuleObjectName(node: ModuleDeclaration): string {
|
||||
return getSourceTextOfNode(node.name);
|
||||
}
|
||||
|
||||
function isExternalModuleSymbol(symbol: Symbol): boolean {
|
||||
return symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length === 1 && symbol.declarations[0].kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
function isNodeParentedBy(node: Node, parent: Node): boolean {
|
||||
while (node) {
|
||||
if (node === parent) return true;
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
name = escapeIdentifier(name);
|
||||
if (container.locals) {
|
||||
for (var node = container; isNodeParentedBy(node, container); node = node.nextLocals) {
|
||||
if (hasProperty(node.locals, name) && node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLocalNameOfContainer(container: Declaration): string {
|
||||
var links = getNodeLinks(container);
|
||||
if (!links.localModuleName) {
|
||||
var name = container.name.text ? unescapeIdentifier(container.name.text) : "M";
|
||||
while (!isUniqueLocalName(name, container)) {
|
||||
name = "_" + name;
|
||||
}
|
||||
links.localModuleName = name;
|
||||
}
|
||||
return links.localModuleName;
|
||||
}
|
||||
|
||||
function getLocalNameForSymbol(symbol: Symbol, location: Node): string {
|
||||
var node = location;
|
||||
while (node) {
|
||||
if ((node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(node) === symbol) {
|
||||
return getLocalNameOfContainer(node);
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
Debug.fail("getLocalNameForSymbol failed");
|
||||
}
|
||||
|
||||
function getExpressionNamePrefix(node: Identifier): string {
|
||||
var symbol = getNodeLinks(node).resolvedSymbol;
|
||||
if (symbol) {
|
||||
@@ -6021,15 +6060,11 @@ module ts {
|
||||
// kind of entity. SymbolFlags.ExportHasLocal encompasses all the kinds that we
|
||||
// do NOT prefix.
|
||||
var exportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
|
||||
var isExportedSymbolFoundInLocalScope = exportSymbol !== symbol;
|
||||
var shouldEmitExportWithoutPrefix = (exportSymbol.flags & SymbolFlags.ExportHasLocal) !== 0;
|
||||
if (isExportedSymbolFoundInLocalScope && !shouldEmitExportWithoutPrefix) {
|
||||
if (symbol !== exportSymbol && !(exportSymbol.flags & SymbolFlags.ExportHasLocal)) {
|
||||
symbol = exportSymbol;
|
||||
}
|
||||
|
||||
// symbol will have a parent if it is an export symbol
|
||||
if (symbol.parent) {
|
||||
return isExternalModuleSymbol(symbol.parent) ? "exports" : symbolToString(symbol.parent);
|
||||
return isExternalModuleSymbol(symbol.parent) ? "exports" : getLocalNameForSymbol(getParentOfSymbol(symbol), node.parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6116,7 +6151,7 @@ module ts {
|
||||
function invokeEmitter() {
|
||||
var resolver: EmitResolver = {
|
||||
getProgram: () => program,
|
||||
getModuleObjectName: getModuleObjectName,
|
||||
getLocalNameOfContainer: getLocalNameOfContainer,
|
||||
getExpressionNamePrefix: getExpressionNamePrefix,
|
||||
getPropertyAccessSubstitution: getPropertyAccessSubstitution,
|
||||
getExportAssignmentName: getExportAssignmentName,
|
||||
|
||||
@@ -1043,7 +1043,7 @@ module ts {
|
||||
emitStart(node.name);
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
var container = getContainingModule(node);
|
||||
write(container ? resolver.getModuleObjectName(container) : "exports");
|
||||
write(container ? resolver.getLocalNameOfContainer(container) : "exports");
|
||||
write(".");
|
||||
}
|
||||
emitNode(node.name);
|
||||
@@ -1444,16 +1444,18 @@ module ts {
|
||||
writeLine();
|
||||
emitStart(node);
|
||||
write("(function (");
|
||||
emit(node.name);
|
||||
emitStart(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
emitEnd(node.name);
|
||||
write(") {");
|
||||
increaseIndent();
|
||||
scopeEmitStart(node);
|
||||
forEach(node.members, member => {
|
||||
writeLine();
|
||||
emitStart(member);
|
||||
emitNode(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
write("[");
|
||||
emitNode(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
write("[");
|
||||
emitQuotedIdentifier(member.name);
|
||||
write("] = ");
|
||||
@@ -1509,7 +1511,9 @@ module ts {
|
||||
}
|
||||
emitStart(node);
|
||||
write("(function (");
|
||||
emit(node.name);
|
||||
emitStart(node.name);
|
||||
write(resolver.getLocalNameOfContainer(node));
|
||||
emitEnd(node.name);
|
||||
write(") ");
|
||||
if (node.body.kind === SyntaxKind.ModuleBlock) {
|
||||
emit(node.body);
|
||||
|
||||
@@ -62,7 +62,12 @@ module ts {
|
||||
|
||||
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
|
||||
export function escapeIdentifier(identifier: string): string {
|
||||
return identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
|
||||
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
|
||||
}
|
||||
|
||||
// Remove extra underscore from escaped identifier
|
||||
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;
|
||||
}
|
||||
|
||||
// Return display name of an identifier
|
||||
|
||||
@@ -142,18 +142,18 @@ module ts {
|
||||
As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
|
||||
IdentifierStart ::
|
||||
Can contain Unicode 3.0.0 categories:
|
||||
“Uppercase letter (Lu)”,
|
||||
“Lowercase letter (Ll)”,
|
||||
“Titlecase letter (Lt)”,
|
||||
“Modifier letter (Lm)”,
|
||||
“Other letter (Lo)”, or
|
||||
“Letter number (Nl)”.
|
||||
Uppercase letter (Lu),
|
||||
Lowercase letter (Ll),
|
||||
Titlecase letter (Lt),
|
||||
Modifier letter (Lm),
|
||||
Other letter (Lo), or
|
||||
Letter number (Nl).
|
||||
IdentifierPart :: =
|
||||
Can contain IdentifierStart + Unicode 3.0.0 categories:
|
||||
“Non-spacing mark (Mn)”,
|
||||
“Combining spacing mark (Mc)”,
|
||||
“Decimal number (Nd)”, or
|
||||
“Connector punctuation (Pc)”.
|
||||
Non-spacing mark (Mn),
|
||||
Combining spacing mark (Mc),
|
||||
Decimal number (Nd), or
|
||||
Connector punctuation (Pc).
|
||||
|
||||
Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
|
||||
http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
|
||||
@@ -165,18 +165,18 @@ module ts {
|
||||
As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
|
||||
IdentifierStart ::
|
||||
Can contain Unicode 6.2 categories:
|
||||
“Uppercase letter (Lu)”,
|
||||
“Lowercase letter (Ll)”,
|
||||
“Titlecase letter (Lt)”,
|
||||
“Modifier letter (Lm)”,
|
||||
“Other letter (Lo)”, or
|
||||
“Letter number (Nl)”.
|
||||
Uppercase letter (Lu),
|
||||
Lowercase letter (Ll),
|
||||
Titlecase letter (Lt),
|
||||
Modifier letter (Lm),
|
||||
Other letter (Lo), or
|
||||
Letter number (Nl).
|
||||
IdentifierPart ::
|
||||
Can contain IdentifierStart + Unicode 6.2 categories:
|
||||
“Non-spacing mark (Mn)”,
|
||||
“Combining spacing mark (Mc)”,
|
||||
“Decimal number (Nd)”,
|
||||
“Connector punctuation (Pc)”,
|
||||
Non-spacing mark (Mn),
|
||||
Combining spacing mark (Mc),
|
||||
Decimal number (Nd),
|
||||
Connector punctuation (Pc),
|
||||
<ZWNJ>, or
|
||||
<ZWJ>.
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@ module ts {
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
nextLocals?: Node; // Next node in declaration order with locals (initialized by binding)
|
||||
}
|
||||
|
||||
export interface NodeArray<T> extends Array<T>, TextRange { }
|
||||
@@ -614,7 +615,7 @@ module ts {
|
||||
|
||||
export interface EmitResolver {
|
||||
getProgram(): Program;
|
||||
getModuleObjectName(node: ModuleDeclaration): string;
|
||||
getLocalNameOfContainer(container: Declaration): string;
|
||||
getExpressionNamePrefix(node: Identifier): string;
|
||||
getPropertyAccessSubstitution(node: PropertyAccess): string;
|
||||
getExportAssignmentName(node: SourceFile): string;
|
||||
@@ -690,7 +691,7 @@ module ts {
|
||||
|
||||
ExportHasLocal = Function | Class | Enum | ValueModule,
|
||||
|
||||
HasLocals = Function | Module | Method | Constructor | Accessor | Signature,
|
||||
HasLocals = Function | Enum | Module | Method | Constructor | Accessor | Signature,
|
||||
HasExports = Class | Enum | Module,
|
||||
HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,
|
||||
|
||||
@@ -742,7 +743,8 @@ module ts {
|
||||
flags?: NodeCheckFlags; // Set of flags specific to Node
|
||||
enumMemberValue?: number; // Constant value of enum member
|
||||
isIllegalTypeReferenceInConstraint?: boolean; // Is type reference in constraint refers to the type parameter from the same list
|
||||
isVisible?: boolean; // Is this node visible
|
||||
isVisible?: boolean; // Is this node visible
|
||||
localModuleName?: string; // Local name for module instance
|
||||
}
|
||||
|
||||
export enum TypeFlags {
|
||||
|
||||
Reference in New Issue
Block a user