Merge branch 'master' into numbersAreHard

Conflicts:
	src/compiler/checker.ts
	tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt
	tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt
This commit is contained in:
Daniel Rosenwasser
2014-10-15 17:07:22 -07:00
320 changed files with 7086 additions and 6285 deletions
+895 -291
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -82,7 +82,7 @@ module ts {
return array1.concat(array2);
}
export function uniqueElements<T>(array: T[]): T[] {
export function deduplicate<T>(array: T[]): T[] {
if (array) {
var result: T[] = [];
for (var i = 0, len = array.length; i < len; i++) {
@@ -114,6 +114,7 @@ module ts {
Cannot_compile_external_modules_unless_the_module_flag_is_provided: { code: 1148, category: DiagnosticCategory.Error, key: "Cannot compile external modules unless the '--module' flag is provided." },
Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: 1149, category: DiagnosticCategory.Error, key: "Filename '{0}' differs from already included filename '{1}' only in casing" },
new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
An_enum_member_cannot_have_a_numeric_name: { code: 1151, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." },
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
@@ -180,8 +181,6 @@ module ts {
The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2363, category: DiagnosticCategory.Error, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
Invalid_left_hand_side_of_assignment_expression: { code: 2364, category: DiagnosticCategory.Error, key: "Invalid left-hand side of assignment expression." },
Operator_0_cannot_be_applied_to_types_1_and_2: { code: 2365, category: DiagnosticCategory.Error, key: "Operator '{0}' cannot be applied to types '{1}' and '{2}'." },
No_best_common_type_exists_between_0_1_and_2: { code: 2366, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}', '{1}', and '{2}'." },
No_best_common_type_exists_between_0_and_1: { code: 2367, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}' and '{1}'." },
Type_parameter_name_cannot_be_0: { code: 2368, category: DiagnosticCategory.Error, key: "Type parameter name cannot be '{0}'" },
A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2369, category: DiagnosticCategory.Error, key: "A parameter property is only allowed in a constructor implementation." },
A_rest_parameter_must_be_of_an_array_type: { code: 2370, category: DiagnosticCategory.Error, key: "A rest parameter must be of an array type." },
+10 -14
View File
@@ -11,7 +11,7 @@
"category": "Error",
"code": 1005
},
"A file cannot have a reference to itself.": {
"A file cannot have a reference to itself.": {
"category": "Error",
"code": 1006
},
@@ -187,7 +187,7 @@
"category": "Error",
"code": 1066
},
"Unexpected token. A constructor, method, accessor, or property was expected." : {
"Unexpected token. A constructor, method, accessor, or property was expected.": {
"category": "Error",
"code": 1068
},
@@ -444,9 +444,13 @@
"code": 1149
},
"'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead.": {
"category": "Error",
"code": 1150
},
"category": "Error",
"code": 1150
},
"An enum member cannot have a numeric name.": {
"category": "Error",
"code": 1151
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -556,7 +560,7 @@
"category": "Error",
"code": 2326
},
"Property '{0}' is optional in type '{1}' but required in type '{2}'.": {
"Property '{0}' is optional in type '{1}' but required in type '{2}'.": {
"category": "Error",
"code": 2327
},
@@ -712,14 +716,6 @@
"category": "Error",
"code": 2365
},
"No best common type exists between '{0}', '{1}', and '{2}'.": {
"category": "Error",
"code": 2366
},
"No best common type exists between '{0}' and '{1}'.": {
"category": "Error",
"code": 2367
},
"Type parameter name cannot be '{0}'": {
"category": "Error",
"code": 2368
+34 -24
View File
@@ -4,8 +4,11 @@
/// <reference path="parser.ts"/>
module ts {
interface EmitTextWriter extends SymbolWriter {
interface EmitTextWriter {
write(s: string): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
@@ -15,6 +18,9 @@ module ts {
getIndent(): number;
}
interface EmitTextWriterWithSymbolWriter extends EmitTextWriter, SymbolWriter{
}
var indentStrings: string[] = ["", " "];
export function getIndentString(level: number) {
if (indentStrings[level] === undefined) {
@@ -28,7 +34,7 @@ module ts {
}
export function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean {
if (!(sourceFile.flags & NodeFlags.DeclarationFile)) {
if (!isDeclarationFile(sourceFile)) {
if ((isExternalModule(sourceFile) || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) {
return true;
}
@@ -38,7 +44,7 @@ module ts {
}
export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) {
return isExternalModule(sourceFile) || (sourceFile.flags & NodeFlags.DeclarationFile) !== 0;
return isExternalModule(sourceFile) || isDeclarationFile(sourceFile);
}
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compilerOnSave feature
@@ -103,7 +109,7 @@ module ts {
};
}
function createTextWriter(trackSymbol: (symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags)=> void): EmitTextWriter {
function createTextWriter(): EmitTextWriter {
var output = "";
var indent = 0;
var lineStart = true;
@@ -149,17 +155,8 @@ module ts {
}
}
function writeKind(text: string, kind: SymbolDisplayPartKind) {
write(text);
}
function writeSymbol(text: string, symbol: Symbol) {
write(text);
}
return {
write: write,
trackSymbol: trackSymbol,
writeKind: writeKind,
writeSymbol: writeSymbol,
rawWrite: rawWrite,
writeLiteral: writeLiteral,
writeLine: writeLine,
@@ -170,7 +167,6 @@ module ts {
getLine: () => lineCount + 1,
getColumn: () => lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1,
getText: () => output,
clear: () => { }
};
}
@@ -318,7 +314,7 @@ module ts {
}
function emitJavaScript(jsFilePath: string, root?: SourceFile) {
var writer = createTextWriter(trackSymbol);
var writer = createTextWriter();
var write = writer.write;
var writeLine = writer.writeLine;
var increaseIndent = writer.increaseIndent;
@@ -374,8 +370,6 @@ module ts {
/** Sourcemap data that will get encoded */
var sourceMapData: SourceMapData;
function trackSymbol(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags) { }
function initializeEmitterWithSourceMaps() {
var sourceMapDir: string; // The directory in which sourcemap will be
@@ -2314,7 +2308,7 @@ module ts {
}
function emitDeclarations(jsFilePath: string, root?: SourceFile) {
var writer = createTextWriter(trackSymbol);
var writer = createTextWriterWithSymbolWriter();
var write = writer.write;
var writeLine = writer.writeLine;
var increaseIndent = writer.increaseIndent;
@@ -2338,11 +2332,24 @@ module ts {
typeName?: Identifier
}
function createTextWriterWithSymbolWriter(): EmitTextWriterWithSymbolWriter {
var writer = <EmitTextWriterWithSymbolWriter>createTextWriter();
writer.trackSymbol = trackSymbol;
writer.writeKeyword = writer.write;
writer.writeOperator = writer.write;
writer.writePunctuation = writer.write;
writer.writeSpace = writer.write;
writer.writeStringLiteral = writer.writeLiteral;
writer.writeParameter = writer.write;
writer.writeSymbol = writer.write;
return writer;
}
function writeAsychronousImportDeclarations(importDeclarations: ImportDeclaration[]) {
var oldWriter = writer;
forEach(importDeclarations, aliasToWrite => {
var aliasEmitInfo = forEach(aliasDeclarationEmitInfo, declEmitInfo => declEmitInfo.declaration === aliasToWrite ? declEmitInfo : undefined);
writer = createTextWriter(trackSymbol);
writer = createTextWriterWithSymbolWriter();
for (var declarationIndent = aliasEmitInfo.indent; declarationIndent; declarationIndent--) {
writer.increaseIndent();
}
@@ -3253,14 +3260,17 @@ module ts {
if (compilerOptions.out) {
emitFile(compilerOptions.out);
}
} else {
// targetSourceFile is specified (e.g calling emitter from language service)
}
else {
// targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
// If shouldEmitToOwnFile is true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
// If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, ".js");
emitFile(jsFilePath, targetSourceFile);
} else {
// If shouldEmitToOwnFile is false, then emit all, non-external-module file, into one single output file
}
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
// Otherwise, if --out is specified and targetSourceFile is not a declaration file,
// Emit all, non-external-module file, into one single output file
emitFile(compilerOptions.out);
}
}
+25 -3
View File
@@ -111,6 +111,10 @@ module ts {
return file.externalModuleIndicator !== undefined;
}
export function isDeclarationFile(file: SourceFile): boolean {
return (file.flags & NodeFlags.DeclarationFile) !== 0;
}
export function isPrologueDirective(node: Node): boolean {
return node.kind === SyntaxKind.ExpressionStatement && (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
}
@@ -221,6 +225,8 @@ module ts {
return child((<ArrayTypeNode>node).elementType);
case SyntaxKind.TupleType:
return children((<TupleTypeNode>node).elementTypes);
case SyntaxKind.UnionType:
return children((<UnionTypeNode>node).types);
case SyntaxKind.ArrayLiteral:
return children((<ArrayLiteral>node).elements);
case SyntaxKind.ObjectLiteral:
@@ -1725,9 +1731,9 @@ module ts {
}
}
function parseType(): TypeNode {
function parseNonUnionType(): TypeNode {
var type = parseNonArrayType();
while (type && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
parseExpected(SyntaxKind.CloseBracketToken);
var node = <ArrayTypeNode>createNode(SyntaxKind.ArrayType, type.pos);
node.elementType = type;
@@ -1736,6 +1742,22 @@ module ts {
return type;
}
function parseType(): TypeNode {
var type = parseNonUnionType();
if (token === SyntaxKind.BarToken) {
var types = <NodeArray<TypeNode>>[type];
types.pos = type.pos;
while (parseOptional(SyntaxKind.BarToken)) {
types.push(parseNonUnionType());
}
types.end = getNodeEnd();
var node = <UnionTypeNode>createNode(SyntaxKind.UnionType, type.pos);
node.types = types;
type = finishNode(node);
}
return type;
}
function parseTypeAnnotation(): TypeNode {
return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined;
}
@@ -4031,7 +4053,7 @@ module ts {
}
}
}
else if (node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || file.flags & NodeFlags.DeclarationFile)) {
else if (node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
// An AmbientExternalModuleDeclaration declares an external module.
// This type of declaration is permitted only in the global module.
+54 -54
View File
@@ -154,6 +154,7 @@ module ts {
TypeLiteral,
ArrayType,
TupleType,
UnionType,
// Expression
ArrayLiteral,
ObjectLiteral,
@@ -224,7 +225,7 @@ module ts {
FirstFutureReservedWord = ImplementsKeyword,
LastFutureReservedWord = YieldKeyword,
FirstTypeNode = TypeReference,
LastTypeNode = TupleType,
LastTypeNode = UnionType,
FirstPunctuation = OpenBraceToken,
LastPunctuation = CaretEqualsToken,
FirstToken = EndOfFileToken,
@@ -337,6 +338,10 @@ module ts {
elementTypes: NodeArray<TypeNode>;
}
export interface UnionTypeNode extends TypeNode {
types: NodeArray<TypeNode>;
}
export interface StringLiteralTypeNode extends TypeNode {
text: string;
}
@@ -648,7 +653,7 @@ module ts {
writeSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
getFullyQualifiedName(symbol: Symbol): string;
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
getRootSymbol(symbol: Symbol): Symbol;
getRootSymbols(symbol: Symbol): Symbol[];
getContextualType(node: Node): Type;
getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
@@ -656,6 +661,8 @@ module ts {
writeTypeParameter(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
writeTypeParametersOfSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
isImplementationOfOverload(node: FunctionDeclaration): boolean;
isUndefinedSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
// Returns the constant value of this enum member, or 'undefined' if the enum member has a
// computed value.
@@ -666,7 +673,12 @@ module ts {
}
export interface SymbolWriter {
writeKind(text: string, kind: SymbolDisplayPartKind): void;
writeKeyword(text: string): void;
writeOperator(text: string): void;
writePunctuation(text: string): void;
writeSpace(text: string): void;
writeStringLiteral(text: string): void;
writeParameter(text: string): void;
writeSymbol(text: string, symbol: Symbol): void;
writeLine(): void;
increaseIndent(): void;
@@ -695,6 +707,9 @@ module ts {
// eg. class C<T> { p: T } <-- Show p as C<T>.p here
// var a: C<number>;
// var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
UseOnlyExternalAliasing = 0x00000002, // Use only external alias information to get the symbol name in the given context
// eg. module m { export class c { } } import x = m.c;
// When this flag is specified m.c will be used to refer to the class instead of alias symbol x
}
export enum SymbolAccessibility {
@@ -752,21 +767,22 @@ module ts {
ConstructSignature = 0x00010000, // Construct signature
IndexSignature = 0x00020000, // Index signature
TypeParameter = 0x00040000, // Type parameter
UnionProperty = 0x00080000, // Property in union type
// Export markers (see comment in declareModuleMember in binder)
ExportValue = 0x00080000, // Exported value marker
ExportType = 0x00100000, // Exported type marker
ExportNamespace = 0x00200000, // Exported namespace marker
ExportValue = 0x00100000, // Exported value marker
ExportType = 0x00200000, // Exported type marker
ExportNamespace = 0x00400000, // Exported namespace marker
Import = 0x00400000, // Import
Instantiated = 0x00800000, // Instantiated symbol
Merged = 0x01000000, // Merged symbol (created during program binding)
Transient = 0x02000000, // Transient symbol (created during type check)
Prototype = 0x04000000, // Symbol for the prototype property (without source code representation)
Import = 0x00800000, // Import
Instantiated = 0x01000000, // Instantiated symbol
Merged = 0x02000000, // Merged symbol (created during program binding)
Transient = 0x04000000, // Transient symbol (created during type check)
Prototype = 0x08000000, // Prototype property (no source representation)
Undefined = 0x10000000, // Symbol for the undefined
Undefined = 0x08000000, // Symbol for the undefined
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty,
Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter,
Namespace = ValueModule | NamespaceModule,
Module = ValueModule | NamespaceModule,
@@ -824,6 +840,7 @@ module ts {
mapper?: TypeMapper; // Type mapper for instantiation alias
referenced?: boolean; // True if alias symbol has been referenced as a value
exportAssignSymbol?: Symbol; // Symbol exported from external module
unionType?: UnionType; // Containing union type for union property
}
export interface TransientSymbol extends Symbol, SymbolLinks { }
@@ -846,14 +863,15 @@ module ts {
}
export interface NodeLinks {
resolvedType?: Type; // Cached type of type node
resolvedSignature?: Signature; // Cached signature of signature node or call expression
resolvedSymbol?: Symbol; // Cached name resolution result
flags?: NodeCheckFlags; // Set of flags specific to Node
enumMemberValue?: number; // Constant value of enum member
resolvedType?: Type; // Cached type of type node
resolvedSignature?: Signature; // Cached signature of signature node or call expression
resolvedSymbol?: Symbol; // Cached name resolution result
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
localModuleName?: string; // Local name for module instance
isVisible?: boolean; // Is this node visible
localModuleName?: string; // Local name for module instance
assignmentChecks?: Map<boolean>; // Cache of assignment checks
}
export enum TypeFlags {
@@ -871,13 +889,14 @@ module ts {
Interface = 0x00000800, // Interface
Reference = 0x00001000, // Generic type reference
Tuple = 0x00002000, // Tuple
Anonymous = 0x00004000, // Anonymous
FromSignature = 0x00008000, // Created for signature assignment check
Union = 0x00004000, // Union
Anonymous = 0x00008000, // Anonymous
FromSignature = 0x00010000, // Created for signature assignment check
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
StringLike = String | StringLiteral,
NumberLike = Number | Enum,
ObjectType = Class | Interface | Reference | Tuple | Anonymous
ObjectType = Class | Interface | Reference | Tuple | Union | Anonymous,
}
// Properties common to all types
@@ -935,6 +954,10 @@ module ts {
baseArrayType: TypeReference; // Array<T> where T is best common type of element types
}
export interface UnionType extends ObjectType {
types: Type[]; // Constituent types
}
// Resolved object type
export interface ResolvedObjectType extends ObjectType {
members: SymbolTable; // Properties by name
@@ -967,6 +990,7 @@ module ts {
hasStringLiterals: boolean; // True if specialized
target?: Signature; // Instantiation target
mapper?: TypeMapper; // Instantiation mapper
unionSignatures?: Signature[]; // Underlying signatures of a union signature
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
}
@@ -981,9 +1005,10 @@ module ts {
}
export interface InferenceContext {
typeParameters: TypeParameter[];
inferences: Type[][];
inferredTypes: Type[];
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
inferenceCount: number; // Incremented for every inference made (whether new or not)
inferences: Type[][]; // Inferences made for each type parameter
inferredTypes: Type[]; // Inferred type for each type parameter
}
export interface DiagnosticMessage {
@@ -1212,32 +1237,7 @@ module ts {
tab = 0x09, // \t
verticalTab = 0x0B, // \v
}
export enum SymbolDisplayPartKind {
aliasName,
className,
enumName,
fieldName,
interfaceName,
keyword,
lineBreak,
numericLiteral,
stringLiteral,
localName,
methodName,
moduleName,
operator,
parameterName,
propertyName,
punctuation,
space,
text,
typeParameterName,
enumMemberName,
functionName,
regularExpressionLiteral,
}
export interface CancellationToken {
isCancellationRequested(): boolean;
}
+14 -2
View File
@@ -146,7 +146,7 @@ module FourSlash {
function convertGlobalOptionsToCompilationSettings(globalOptions: { [idx: string]: string }): ts.CompilationSettings {
var settings: ts.CompilationSettings = {};
// Convert all property in globalOptions into ts.CompilationSettings
// Convert all property in globalOptions into ts.CompilationSettings
for (var prop in globalOptions) {
if (globalOptions.hasOwnProperty(prop)) {
switch (prop) {
@@ -1610,7 +1610,7 @@ module FourSlash {
Harness.IO.log(this.getNameOrDottedNameSpan(pos));
}
private verifyClassifications(expected: { classificationType: string; text: string }[], actual: ts.ClassifiedSpan[]) {
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
if (actual.length !== expected.length) {
this.raiseError('verifyClassifications failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length);
}
@@ -1626,7 +1626,19 @@ module FourSlash {
actualClassification.classificationType);
}
var expectedSpan = expectedClassification.textSpan;
var actualSpan = actualClassification.textSpan;
if (expectedSpan) {
var expectedLength = expectedSpan.end - expectedSpan.start;
if (expectedSpan.start !== actualSpan.start() || expectedLength !== actualSpan.length()) {
this.raiseError("verifyClassifications failed - expected span of text to be " +
"{start=" + expectedSpan.start + ", length=" + expectedLength + "}, but was " +
"{start=" + actualSpan.start() + ", length=" + actualSpan.length() + "}");
}
}
var actualText = this.activeFile.content.substr(actualSpan.start(), actualSpan.length());
if (expectedClassification.text !== actualText) {
this.raiseError('verifyClassifications failed - expected classificatied text to be ' +
@@ -476,8 +476,6 @@ module TypeScript {
//}
}
var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
var funcSignature = funcPullDecl.getSignatureSymbol(this.semanticInfoChain);
this.emitDeclarationComments(funcDecl);
this.emitIndent();
@@ -603,11 +601,6 @@ module TypeScript {
private emitConstructSignature(funcDecl: ConstructSignatureSyntax) {
var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
var start = new Date().getTime();
var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);
TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;
this.emitDeclarationComments(funcDecl);
this.emitIndent();
@@ -633,11 +626,6 @@ module TypeScript {
private emitMethodSignature(funcDecl: MethodSignatureSyntax) {
var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
var start = new Date().getTime();
var funcSymbol = this.semanticInfoChain.getSymbolForAST(funcDecl);
TypeScript.declarationEmitFunctionDeclarationGetSymbolTime += new Date().getTime() - start;
this.emitDeclarationComments(funcDecl);
this.emitIndent();
@@ -817,7 +805,6 @@ module TypeScript {
var parameter = funcDecl.callSignature.parameterList.parameters[i];
var parameterDecl = this.semanticInfoChain.getDeclForAST(parameter);
if (hasFlag(parameterDecl.flags, PullElementFlags.PropertyParameter)) {
var funcPullDecl = this.semanticInfoChain.getDeclForAST(funcDecl);
this.emitDeclarationComments(parameter);
this.declFile.Write(this.getIndentString());
this.emitClassElementModifiers(parameter.modifiers);
@@ -838,7 +825,6 @@ module TypeScript {
var className = classDecl.identifier.text();
this.emitDeclarationComments(classDecl);
var classPullDecl = this.semanticInfoChain.getDeclForAST(classDecl);
this.emitDeclFlags(classDecl, "class");
this.declFile.Write(className);
@@ -934,7 +920,6 @@ module TypeScript {
var interfaceName = interfaceDecl.identifier.text();
this.emitDeclarationComments(interfaceDecl);
var interfacePullDecl = this.semanticInfoChain.getDeclForAST(interfaceDecl);
this.emitDeclFlags(interfaceDecl, "interface");
this.declFile.Write(interfaceName);
@@ -980,7 +965,6 @@ module TypeScript {
}
this.emitDeclarationComments(moduleDecl);
var modulePullDecl = this.semanticInfoChain.getDeclForAST(moduleDecl);
this.emitDeclFlags(moduleDecl, "enum");
this.declFile.WriteLine(moduleDecl.identifier.text() + " {");
+1 -5
View File
@@ -512,7 +512,7 @@ module TypeScript {
for (var i = 0, n = fileNames.length; i < n; i++) {
var fileName = fileNames[i];
var document = this.getDocument(fileNames[i]);
var document = this.getDocument(fileName);
sharedEmitter = this._emitDocumentDeclarations(document, emitOptions,
file => emitOutput.outputFiles.push(file), sharedEmitter);
@@ -578,7 +578,6 @@ module TypeScript {
var sourceUnit = document.sourceUnit();
Debug.assert(this._shouldEmit(document));
var typeScriptFileName = document.fileName;
if (!emitter) {
var javaScriptFileName = this.mapOutputFileName(document, emitOptions, TypeScriptCompiler.mapToJSFileName);
var outFile = new TextWriter(javaScriptFileName, this.writeByteOrderMarkForDocument(document), OutputFileType.JavaScript);
@@ -799,8 +798,6 @@ module TypeScript {
}
private extractResolutionContextFromAST(resolver: PullTypeResolver, ast: ISyntaxElement, document: Document, propagateContextualTypes: boolean): { ast: ISyntaxElement; enclosingDecl: PullDecl; resolutionContext: PullTypeResolutionContext; inContextuallyTypedAssignment: boolean; inWithBlock: boolean; } {
var scriptName = document.fileName;
var enclosingDecl: PullDecl = null;
var enclosingDeclAST: ISyntaxElement = null;
var inContextuallyTypedAssignment = false;
@@ -981,7 +978,6 @@ module TypeScript {
case SyntaxKind.ReturnStatement:
if (propagateContextualTypes) {
var returnStatement = <ReturnStatementSyntax>current;
var contextualType: PullTypeSymbol = null;
if (enclosingDecl && (enclosingDecl.kind & PullElementKind.SomeFunction)) {
-6
View File
@@ -7,12 +7,6 @@ module TypeScript {
}
export function integerMultiplyLow32Bits(n1: number, n2: number): number {
var n1Low16 = n1 & 0x0000ffff;
var n1High16 = n1 >>> 16;
var n2Low16 = n2 & 0x0000ffff;
var n2High16 = n2 >>> 16;
var resultLow32 = (((n1 & 0xffff0000) * n2) >>> 0) + (((n1 & 0x0000ffff) * n2) >>> 0) >>> 0;
return resultLow32;
}
+216 -116
View File
@@ -994,12 +994,37 @@ module ts {
containerKind: string;
containerName: string;
}
export enum SymbolDisplayPartKind {
aliasName,
className,
enumName,
fieldName,
interfaceName,
keyword,
lineBreak,
numericLiteral,
stringLiteral,
localName,
methodName,
moduleName,
operator,
parameterName,
propertyName,
punctuation,
space,
text,
typeParameterName,
enumMemberName,
functionName,
regularExpressionLiteral,
}
export interface SymbolDisplayPart {
text: string;
kind: string;
}
export interface QuickInfo {
kind: string;
kindModifiers: string;
@@ -1306,7 +1331,12 @@ module ts {
resetWriter();
return {
displayParts: () => displayParts,
writeKind: writeKind,
writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword),
writeOperator: text => writeKind(text, SymbolDisplayPartKind.operator),
writePunctuation: text => writeKind(text, SymbolDisplayPartKind.punctuation),
writeSpace: text => writeKind(text, SymbolDisplayPartKind.space),
writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral),
writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName),
writeSymbol: writeSymbol,
writeLine: writeLine,
increaseIndent: () => { indent++; },
@@ -2250,7 +2280,7 @@ module ts {
return undefined;
}
function createCompletionEntry(symbol: Symbol): CompletionEntry {
function createCompletionEntry(symbol: Symbol, typeChecker: TypeChecker): CompletionEntry {
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
// We would like to only show things that can be added after a dot, so for instance numeric properties can
// not be accessed with a dot (a.1 <- invalid)
@@ -2265,7 +2295,7 @@ module ts {
// We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration.
return {
name: displayName,
kind: getSymbolKind(symbol, SemanticMeaning.All),
kind: getSymbolKind(symbol, typeChecker),
kindModifiers: getSymbolModifiers(symbol)
};
}
@@ -2273,7 +2303,7 @@ module ts {
function getCompletionsAtPosition(filename: string, position: number, isMemberCompletion: boolean) {
function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void {
forEach(symbols, symbol => {
var entry = createCompletionEntry(symbol);
var entry = createCompletionEntry(symbol, session.typeChecker);
if (entry && !lookUp(session.symbols, entry.name)) {
session.entries.push(entry);
session.symbols[entry.name] = symbol;
@@ -2612,7 +2642,7 @@ module ts {
if (symbol) {
var type = session.typeChecker.getTypeOfSymbol(symbol);
Debug.assert(type, "Could not find type for symbol");
var completionEntry = createCompletionEntry(symbol);
var completionEntry = createCompletionEntry(symbol, session.typeChecker);
// TODO(drosen): Right now we just permit *all* semantic meanings when calling 'getSymbolKind'
// which is permissible given that it is backwards compatible; but really we should consider
// passing the meaning for the node so that we don't report that a suggestion for a value is an interface.
@@ -2660,20 +2690,16 @@ module ts {
}
}
function getSymbolKind(symbol: Symbol, meaningAtLocation: SemanticMeaning): string {
var flags = typeInfoResolver.getRootSymbol(symbol).getFlags();
// TODO(drosen): use contextual SemanticMeaning.
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker): string {
var flags = typeInfoResolver.getRootSymbols(symbol)[0].getFlags();
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement;
// The following should only apply if encountered at a type position,
// and need to have precedence over other meanings if this is the case.
if (meaningAtLocation & SemanticMeaning.Type) {
if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement;
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
}
var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags);
if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement;
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver);
if (result === ScriptElementKind.unknown) {
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement;
@@ -2683,16 +2709,19 @@ module ts {
return result;
}
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags) {
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, typeResolver: TypeChecker) {
if (typeResolver.isUndefinedSymbol(symbol)) {
return ScriptElementKind.variableElement;
}
if (typeResolver.isArgumentsSymbol(symbol)) {
return ScriptElementKind.localVariableElement;
}
if (flags & SymbolFlags.Variable) {
if (isFirstDeclarationOfSymbolParameter(symbol)) {
return ScriptElementKind.parameterElement;
}
return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement;
}
if (flags & SymbolFlags.Undefined) {
return ScriptElementKind.variableElement;
}
if (flags & SymbolFlags.Function) return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement;
if (flags & SymbolFlags.GetAccessor) return ScriptElementKind.memberGetAccessorElement;
if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement;
@@ -2751,19 +2780,15 @@ module ts {
semanticMeaning = getMeaningFromLocation(location)) {
var displayParts: SymbolDisplayPart[] = [];
var documentation: SymbolDisplayPart[];
var symbolFlags = typeResolver.getRootSymbol(symbol).flags;
var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags);
var symbolFlags = typeResolver.getRootSymbols(symbol)[0].flags;
var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver);
var hasAddedSymbolInfo: boolean;
// Class at constructor site need to be shown as constructor apart from property,method, vars
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Signature || symbolFlags & SymbolFlags.Class) {
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Import) {
// If it is accessor they are allowed only if location is at name of the accessor
if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
symbolKind = ScriptElementKind.memberVariableElement;
}
else if (symbol.name === "undefined") {
// undefined is symbol and not property
symbolKind = ScriptElementKind.variableElement;
}
var type = typeResolver.getTypeOfSymbol(symbol);
if (type) {
@@ -2796,6 +2821,18 @@ module ts {
symbolKind = ScriptElementKind.constructorImplementationElement;
addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
}
else if (symbolFlags & SymbolFlags.Import) {
symbolKind = ScriptElementKind.alias;
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
displayParts.push(textPart(symbolKind));
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
displayParts.push(spacePart());
if (useConstructSignatures) {
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
displayParts.push(spacePart());
}
addFullSymbolName(symbol);
}
else {
addPrefixForAnyFunctionOrVar(symbol, symbolKind);
}
@@ -2856,27 +2893,27 @@ module ts {
if (symbolFlags & SymbolFlags.Class && !hasAddedSymbolInfo) {
displayParts.push(keywordPart(SyntaxKind.ClassKeyword));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments));
addFullSymbolName(symbol);
writeTypeParametersOfSymbol(symbol, sourceFile);
}
if ((symbolFlags & SymbolFlags.Interface) && (semanticMeaning & SemanticMeaning.Type)) {
addNewLineIfDisplayPartsExist();
displayParts.push(keywordPart(SyntaxKind.InterfaceKeyword));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments));
addFullSymbolName(symbol);
writeTypeParametersOfSymbol(symbol, sourceFile);
}
if (symbolFlags & SymbolFlags.Enum) {
addNewLineIfDisplayPartsExist();
displayParts.push(keywordPart(SyntaxKind.EnumKeyword));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile));
addFullSymbolName(symbol);
}
if (symbolFlags & SymbolFlags.Module) {
addNewLineIfDisplayPartsExist();
displayParts.push(keywordPart(SyntaxKind.ModuleKeyword));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile));
addFullSymbolName(symbol);
}
if ((symbolFlags & SymbolFlags.TypeParameter) && (semanticMeaning & SemanticMeaning.Type)) {
addNewLineIfDisplayPartsExist();
@@ -2884,13 +2921,13 @@ module ts {
displayParts.push(textPart("type parameter"));
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, enclosingDeclaration));
addFullSymbolName(symbol);
displayParts.push(spacePart());
displayParts.push(keywordPart(SyntaxKind.InKeyword));
displayParts.push(spacePart());
if (symbol.parent) {
// Class/Interface type parameter
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol.parent, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments))
addFullSymbolName(symbol.parent, enclosingDeclaration);
writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
}
else {
@@ -2902,7 +2939,7 @@ module ts {
displayParts.push(spacePart());
}
else if (signatureDeclaration.kind !== SyntaxKind.CallSignature && signatureDeclaration.name) {
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, signatureDeclaration.symbol, sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments))
addFullSymbolName(signatureDeclaration.symbol);
}
displayParts.push.apply(displayParts, signatureToDisplayParts(typeResolver, signature, sourceFile, TypeFormatFlags.WriteTypeArgumentsOfSignature));
}
@@ -2922,18 +2959,37 @@ module ts {
}
if (symbolFlags & SymbolFlags.Import) {
addNewLineIfDisplayPartsExist();
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
displayParts.push(textPart("alias"));
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
displayParts.push(spacePart());
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile));
addFullSymbolName(symbol);
displayParts.push(spacePart());
displayParts.push(punctuationPart(SyntaxKind.EqualsToken));
displayParts.push(spacePart());
ts.forEach(symbol.declarations, declaration => {
if (declaration.kind === SyntaxKind.ImportDeclaration) {
var importDeclaration = <ImportDeclaration>declaration;
if (importDeclaration.externalModuleName) {
displayParts.push(keywordPart(SyntaxKind.RequireKeyword));
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
displayParts.push(displayPart(getTextOfNode(importDeclaration.externalModuleName), SymbolDisplayPartKind.stringLiteral));
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
}
else {
var internalAliasSymbol = typeResolver.getSymbolInfo(importDeclaration.entityName);
addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
}
return true;
}
});
}
if (!hasAddedSymbolInfo) {
if (symbolKind !== ScriptElementKind.unknown) {
if (type) {
addPrefixForAnyFunctionOrVar(symbol, symbolKind);
// For properties, variables and local vars: show the type
if (symbolKind === ScriptElementKind.memberVariableElement ||
symbolFlags & SymbolFlags.Variable) {
symbolFlags & SymbolFlags.Variable ||
symbolKind === ScriptElementKind.localVariableElement) {
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
displayParts.push(spacePart());
// If the type is type parameter, format it specially
@@ -2958,7 +3014,7 @@ module ts {
}
}
else {
symbolKind = getSymbolKind(symbol, semanticMeaning);
symbolKind = getSymbolKind(symbol, typeResolver);
}
}
@@ -2974,6 +3030,12 @@ module ts {
}
}
function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) {
var fullSymbolDisplayParts = symbolToDisplayParts(typeResolver, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing);
displayParts.push.apply(displayParts, fullSymbolDisplayParts);
}
function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) {
addNewLineIfDisplayPartsExist();
if (symbolKind) {
@@ -2981,8 +3043,7 @@ module ts {
displayParts.push(textPart(symbolKind));
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
displayParts.push(spacePart());
// Write type parameters of class/Interface if it is property/method of the generic class/interface
displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, symbol, sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments));
addFullSymbolName(symbol);
}
}
@@ -3020,12 +3081,6 @@ module ts {
var symbol = typeInfoResolver.getSymbolInfo(node);
if (!symbol) {
return undefined;
}
var symbol = typeInfoResolver.getSymbolInfo(node);
if (!symbol) {
// Try getting just type at this position and show
switch (node.kind) {
case SyntaxKind.Identifier:
@@ -3033,7 +3088,7 @@ module ts {
case SyntaxKind.QualifiedName:
case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword:
// For the identifiers/this/usper etc get the type at position
// For the identifiers/this/super etc get the type at position
var type = typeInfoResolver.getTypeOfNode(node);
if (type) {
return {
@@ -3060,7 +3115,7 @@ module ts {
}
/// Goto definition
function getDefinitionAtPosition(filename: string, position: number): DefinitionInfo[]{
function getDefinitionAtPosition(filename: string, position: number): DefinitionInfo[] {
function getDefinitionInfo(node: Node, symbolKind: string, symbolName: string, containerName: string): DefinitionInfo {
return {
fileName: node.getSourceFile().filename,
@@ -3092,7 +3147,7 @@ module ts {
result.push(getDefinitionInfo(declarations[declarations.length - 1], symbolKind, symbolName, containerName));
return true;
}
return false;
}
@@ -3156,7 +3211,7 @@ module ts {
// Could not find a symbol e.g. node is string or number keyword,
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
if (!symbol || !(symbol.getDeclarations())) {
if (!symbol) {
return undefined;
}
@@ -3164,7 +3219,7 @@ module ts {
var declarations = symbol.getDeclarations();
var symbolName = typeInfoResolver.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
var symbolKind = getSymbolKind(symbol, getMeaningFromLocation(node));
var symbolKind = getSymbolKind(symbol, typeInfoResolver);
var containerSymbol = symbol.parent;
var containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : "";
@@ -3689,18 +3744,20 @@ module ts {
return [getReferenceEntryFromNode(node)];
}
// the symbol was an internal symbol and does not have a declaration e.g.undefined symbol
if (!symbol.getDeclarations()) {
var declarations = symbol.declarations;
// The symbol was an internal symbol and does not have a declaration e.g.undefined symbol
if (!declarations || !declarations.length) {
return undefined;
}
var result: ReferenceEntry[];
// Compute the meaning from the location and the symbol it references
var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.getDeclarations());
var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations);
// Get the text to search for, we need to normalize it as external module names will have quote
var symbolName = getNormalizedSymbolName(symbol);
var symbolName = getNormalizedSymbolName(symbol.name, declarations);
// Get syntactic diagnostics
var scope = getSymbolScope(symbol);
@@ -3722,15 +3779,15 @@ module ts {
return result;
function getNormalizedSymbolName(symbol: Symbol): string {
function getNormalizedSymbolName(symbolName: string, declarations: Declaration[]): string {
// Special case for function expressions, whose names are solely local to their bodies.
var functionExpression = getDeclarationOfKind(symbol, SyntaxKind.FunctionExpression);
var functionExpression = forEach(declarations, d => d.kind === SyntaxKind.FunctionExpression ? d : undefined);
if (functionExpression && functionExpression.name) {
var name = functionExpression.name.text;
}
else {
var name = symbol.name;
var name = symbolName;
}
var length = name.length;
@@ -3757,22 +3814,24 @@ module ts {
var scope: Node = undefined;
var declarations = symbol.getDeclarations();
for (var i = 0, n = declarations.length; i < n; i++) {
var container = getContainerNode(declarations[i]);
if (declarations) {
for (var i = 0, n = declarations.length; i < n; i++) {
var container = getContainerNode(declarations[i]);
if (scope && scope !== container) {
// Different declarations have different containers, bail out
return undefined;
if (scope && scope !== container) {
// Different declarations have different containers, bail out
return undefined;
}
if (container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container)) {
// This is a global variable and not an external module, any declaration defined
// within this scope is visible outside the file
return undefined;
}
// The search scope is the container node
scope = container;
}
if (container.kind === SyntaxKind.SourceFile && !isExternalModule(<SourceFile>container)) {
// This is a global variable and not an external module, any declaration defined
// within this scope is visible outside the file
return undefined;
}
// The search scope is the container node
scope = container;
}
return scope;
@@ -3908,14 +3967,7 @@ module ts {
}
var referenceSymbol = typeInfoResolver.getSymbolInfo(referenceLocation);
// Could not find a symbol e.g. node is string or number keyword,
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
if (!referenceSymbol || !(referenceSymbol.getDeclarations())) {
return;
}
if (isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) {
if (referenceSymbol && isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) {
result.push(getReferenceEntryFromNode(referenceLocation));
}
});
@@ -4077,24 +4129,27 @@ module ts {
// The search set contains at least the current symbol
var result = [symbol];
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
var rootSymbol = typeInfoResolver.getRootSymbol(symbol);
if (rootSymbol && rootSymbol !== symbol) {
result.push(rootSymbol);
}
// If the location is in a context sensitive location (i.e. in an object literal) try
// to get a contextual type for it, and add the property symbol from the contextual
// type to the search set
if (isNameOfPropertyAssignment(location)) {
var symbolFromContextualType = getPropertySymbolFromContextualType(location);
if (symbolFromContextualType) result.push(typeInfoResolver.getRootSymbol(symbolFromContextualType));
forEach(getPropertySymbolsFromContextualType(location), contextualSymbol => {
result.push.apply(result, typeInfoResolver.getRootSymbols(contextualSymbol));
});
}
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
if (symbol.parent && symbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
getPropertySymbolsFromBaseTypes(symbol.parent, symbol.getName(), result);
}
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => {
if (rootSymbol !== symbol) {
result.push(rootSymbol);
}
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
}
});
return result;
}
@@ -4130,11 +4185,7 @@ module ts {
}
function isRelatableToSearchSet(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node): boolean {
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
var referenceSymbolTarget = typeInfoResolver.getRootSymbol(referenceSymbol);
// if it is in the list, then we are done
if (searchSymbols.indexOf(referenceSymbolTarget) >= 0) {
if (searchSymbols.indexOf(referenceSymbol) >= 0) {
return true;
}
@@ -4142,29 +4193,61 @@ module ts {
// object literal, lookup the property symbol in the contextual type, and use this symbol to
// compare to our searchSymbol
if (isNameOfPropertyAssignment(referenceLocation)) {
var symbolFromContextualType = getPropertySymbolFromContextualType(referenceLocation);
if (symbolFromContextualType && searchSymbols.indexOf(typeInfoResolver.getRootSymbol(symbolFromContextualType)) >= 0) {
return forEach(getPropertySymbolsFromContextualType(referenceLocation), contextualSymbol => {
return forEach(typeInfoResolver.getRootSymbols(contextualSymbol), s => searchSymbols.indexOf(s) >= 0);
});
}
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
// Or a union property, use its underlying unioned symbols
return forEach(typeInfoResolver.getRootSymbols(referenceSymbol), rootSymbol => {
// if it is in the list, then we are done
if (searchSymbols.indexOf(rootSymbol) >= 0) {
return true;
}
}
// Finally, try all properties with the same name in any type the containing type extend or implemented, and
// see if any is in the list
if (referenceSymbol.parent && referenceSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
var result: Symbol[] = [];
getPropertySymbolsFromBaseTypes(referenceSymbol.parent, referenceSymbol.getName(), result);
return forEach(result, s => searchSymbols.indexOf(s) >= 0);
}
// Finally, try all properties with the same name in any type the containing type extended or implemented, and
// see if any is in the list
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
var result: Symbol[] = [];
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
return forEach(result, s => searchSymbols.indexOf(s) >= 0);
}
return false;
return false;
});
}
function getPropertySymbolFromContextualType(node: Node): Symbol {
function getPropertySymbolsFromContextualType(node: Node): Symbol[] {
if (isNameOfPropertyAssignment(node)) {
var objectLiteral = node.parent.parent;
var contextualType = typeInfoResolver.getContextualType(objectLiteral);
var name = (<Identifier>node).text;
if (contextualType) {
return typeInfoResolver.getPropertyOfType(contextualType, (<Identifier>node).text);
if (contextualType.flags & TypeFlags.Union) {
// This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types)
// if not, search the constituent types for the property
var unionProperty = contextualType.getProperty(name)
if (unionProperty) {
return [unionProperty];
}
else {
var result: Symbol[] = [];
forEach((<UnionType>contextualType).types, t => {
var symbol = t.getProperty(name);
if (symbol) {
result.push(symbol);
}
});
return result;
}
}
else {
var symbol = contextualType.getProperty(name);
if (symbol) {
return [symbol];
}
}
}
}
return undefined;
@@ -4681,7 +4764,24 @@ module ts {
}
}
else if (flags & SymbolFlags.Module) {
return ClassificationTypeNames.moduleName;
// Only classify a module as such if
// - It appears in a namespace context.
// - There exists a module declaration which actually impacts the value side.
if (meaningAtPosition & SemanticMeaning.Namespace ||
(meaningAtPosition & SemanticMeaning.Value && hasValueSideModule(symbol))) {
return ClassificationTypeNames.moduleName;
}
}
return undefined;
/**
* Returns true if there exists a module that introduces entities on the value side.
*/
function hasValueSideModule(symbol: Symbol): boolean {
return forEach(symbol.declarations, declaration => {
return declaration.kind === SyntaxKind.ModuleDeclaration && isInstantiated(declaration);
});
}
}
@@ -5152,7 +5252,7 @@ module ts {
// Only allow a symbol to be renamed if it actually has at least one declaration.
if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) {
var kind = getSymbolKind(symbol, getMeaningFromLocation(node));
var kind = getSymbolKind(symbol, typeInfoResolver);
if (kind) {
return getRenameInfo(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind,
getSymbolModifiers(symbol),
-1
View File
@@ -84,7 +84,6 @@ module TypeScript {
private cacheSyntaxTreeInfo(): void {
// If we're not keeping around the syntax tree, store the diagnostics and line
// map so they don't have to be recomputed.
var sourceUnit = this.sourceUnit();
var firstToken = firstSyntaxTreeToken(this);
var leadingTrivia = firstToken.leadingTrivia(this.text);