Merge branch 'master' into testPerf

This commit is contained in:
Daniel Rosenwasser
2015-05-15 14:44:22 -07:00
397 changed files with 6555 additions and 4548 deletions
+12
View File
@@ -440,6 +440,18 @@ module ts {
else if (isBlockOrCatchScoped(<Declaration>node)) {
bindBlockScopedVariableDeclaration(<Declaration>node);
}
else if (isParameterDeclaration(<VariableLikeDeclaration>node)) {
// It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
// because its parent chain has already been set up, since parents are set before descending into children.
//
// If node is a binding element in parameter declaration, we need to use ParameterExcludes.
// Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
// For example:
// function foo([a,a]) {} // Duplicate Identifier error
// function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
// // which correctly set excluded symbols
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false);
}
+62 -30
View File
@@ -88,6 +88,7 @@ module ts {
let undefinedType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
let nullType = createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsUndefinedOrNull, "null");
let unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
let circularType = createIntrinsicType(TypeFlags.Any, "__circular__");
let emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@@ -803,7 +804,9 @@ module ts {
let symbol: Symbol;
if (name.kind === SyntaxKind.Identifier) {
symbol = resolveName(name, (<Identifier>name).text, meaning, Diagnostics.Cannot_find_name_0, <Identifier>name);
let message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
symbol = resolveName(name, (<Identifier>name).text, meaning, message, <Identifier>name);
if (!symbol) {
return undefined;
}
@@ -855,10 +858,11 @@ module ts {
return symbol;
}
}
let fileName: string;
let sourceFile: SourceFile;
while (true) {
let fileName = normalizePath(combinePaths(searchPath, moduleName));
sourceFile = host.getSourceFile(fileName + ".ts") || host.getSourceFile(fileName + ".d.ts");
fileName = normalizePath(combinePaths(searchPath, moduleName));
sourceFile = forEach(supportedExtensions, extension => host.getSourceFile(fileName + extension));
if (sourceFile || isRelative) {
break;
}
@@ -2048,13 +2052,6 @@ module ts {
return resolutionResults.pop();
}
function getRootDeclaration(node: Node): Node {
while (node.kind === SyntaxKind.BindingElement) {
node = node.parent.parent;
}
return node;
}
function getDeclarationContainer(node: Node): Node {
node = getRootDeclaration(node);
@@ -2412,7 +2409,16 @@ module ts {
function getTypeOfAlias(symbol: Symbol): Type {
let links = getSymbolLinks(symbol);
if (!links.type) {
links.type = getTypeOfSymbol(resolveAlias(symbol));
let targetSymbol = resolveAlias(symbol);
// It only makes sense to get the type of a value symbol. If the result of resolving
// the alias is not a value, then it has no type. To get the type associated with a
// type symbol, call getDeclaredTypeOfSymbol.
// This check is important because without it, a call to getTypeOfSymbol could end
// up recursively calling getTypeOfAlias, causing a stack overflow.
links.type = targetSymbol.flags & SymbolFlags.Value
? getTypeOfSymbol(targetSymbol)
: unknownType;
}
return links.type;
}
@@ -3632,10 +3638,20 @@ module ts {
return type;
}
// Subtype reduction is basically an optimization we do to avoid excessively large union types, which take longer
// to process and look strange in quick info and error messages. Semantically there is no difference between the
// reduced type and the type itself. So, when we detect a circularity we simply say that the reduced type is the
// type itself.
function getReducedTypeOfUnionType(type: UnionType): Type {
// If union type was created without subtype reduction, perform the deferred reduction now
if (!type.reducedType) {
type.reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false);
type.reducedType = circularType;
let reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false);
if (type.reducedType === circularType) {
type.reducedType = reducedType;
}
}
else if (type.reducedType === circularType) {
type.reducedType = type;
}
return type.reducedType;
}
@@ -5382,20 +5398,43 @@ module ts {
if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
return type;
}
// Target type is type of prototype property
let targetType: Type;
let prototypeProperty = getPropertyOfType(rightType, "prototype");
if (!prototypeProperty) {
return type;
if (prototypeProperty) {
// Target type is type of the protoype property
let prototypePropertyType = getTypeOfSymbol(prototypeProperty);
if (prototypePropertyType !== anyType) {
targetType = prototypePropertyType;
}
}
let targetType = getTypeOfSymbol(prototypeProperty);
// Narrow to target type if it is a subtype of current type
if (isTypeSubtypeOf(targetType, type)) {
return targetType;
if (!targetType) {
// Target type is type of construct signature
let constructSignatures: Signature[];
if (rightType.flags & TypeFlags.Interface) {
constructSignatures = resolveDeclaredMembers(<InterfaceType>rightType).declaredConstructSignatures;
}
else if (rightType.flags & TypeFlags.Anonymous) {
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
}
if (constructSignatures && constructSignatures.length) {
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
}
}
// If current type is a union type, remove all constituents that aren't subtypes of target type
if (type.flags & TypeFlags.Union) {
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
if (targetType) {
// Narrow to the target type if it's a subtype of the current type
if (isTypeSubtypeOf(targetType, type)) {
return targetType;
}
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
if (type.flags & TypeFlags.Union) {
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
}
}
return type;
}
@@ -9180,13 +9219,6 @@ module ts {
}
}
function isParameterDeclaration(node: VariableLikeDeclaration) {
while (node.kind === SyntaxKind.BindingElement) {
node = <VariableLikeDeclaration>node.parent.parent;
}
return node.kind === SyntaxKind.Parameter;
}
// Check that a parameter initializer contains no references to parameters declared to the right of itself
function checkParameterInitializer(node: VariableLikeDeclaration): void {
if (getRootDeclaration(node).kind !== SyntaxKind.Parameter) {
+1 -1
View File
@@ -88,7 +88,7 @@ module ts {
{
name: "noEmitOnError",
type: "boolean",
description: Diagnostics.Do_not_emit_outputs_if_any_type_checking_errors_were_reported,
description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
},
{
name: "noImplicitAny",
+17 -5
View File
@@ -459,8 +459,18 @@ module ts {
if (path.charCodeAt(2) === CharacterCodes.slash) return 3;
return 2;
}
// Per RFC 1738 'file' URI schema has the shape file://<host>/<path>
// if <host> is omitted then it is assumed that host value is 'localhost',
// however slash after the omitted <host> is not removed.
// file:///folder1/file1 - this is a correct URI
// file://folder2/file2 - this is an incorrect URI
if (path.lastIndexOf("file:///", 0) === 0) {
return "file:///".length;
}
let idx = path.indexOf('://');
if (idx !== -1) return idx + 3
if (idx !== -1) {
return idx + "://".length;
}
return 0;
}
@@ -640,16 +650,18 @@ module ts {
return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
}
let supportedExtensions = [".d.ts", ".ts", ".js"];
/**
* List of supported extensions in order of file resolution precedence.
*/
export const supportedExtensions = [".ts", ".d.ts"];
const extensionsToRemove = [".d.ts", ".ts", ".js"];
export function removeFileExtension(path: string): string {
for (let ext of supportedExtensions) {
for (let ext of extensionsToRemove) {
if (fileExtensionIs(path, ext)) {
return path.substr(0, path.length - ext.length);
}
}
return path;
}
@@ -364,6 +364,7 @@ module ts {
A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: { code: 2500, category: DiagnosticCategory.Error, key: "A class can only implement an identifier/qualified-name with optional type arguments." },
A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." },
_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." },
Cannot_find_namespace_0: { code: 2503, category: DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@@ -443,8 +444,8 @@ module ts {
Unknown_compiler_option_0: { code: 5023, category: DiagnosticCategory.Error, key: "Unknown compiler option '{0}'." },
Compiler_option_0_requires_a_value_of_type_1: { code: 5024, category: DiagnosticCategory.Error, key: "Compiler option '{0}' requires a value of type {1}." },
Could_not_write_file_0_Colon_1: { code: 5033, category: DiagnosticCategory.Error, key: "Could not write file '{0}': {1}" },
Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5038, category: DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified without specifying 'sourcemap' option." },
Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5039, category: DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified without specifying 'sourcemap' option." },
Option_mapRoot_cannot_be_specified_without_specifying_sourceMap_option: { code: 5038, category: DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified without specifying 'sourceMap' option." },
Option_sourceRoot_cannot_be_specified_without_specifying_sourceMap_option: { code: 5039, category: DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified without specifying 'sourceMap' option." },
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
@@ -464,7 +465,7 @@ module ts {
Watch_input_files: { code: 6005, category: DiagnosticCategory.Message, key: "Watch input files." },
Redirect_output_structure_to_the_directory: { code: 6006, category: DiagnosticCategory.Message, key: "Redirect output structure to the directory." },
Do_not_erase_const_enum_declarations_in_generated_code: { code: 6007, category: DiagnosticCategory.Message, key: "Do not erase const enum declarations in generated code." },
Do_not_emit_outputs_if_any_type_checking_errors_were_reported: { code: 6008, category: DiagnosticCategory.Message, key: "Do not emit outputs if any type checking errors were reported." },
Do_not_emit_outputs_if_any_errors_were_reported: { code: 6008, category: DiagnosticCategory.Message, key: "Do not emit outputs if any errors were reported." },
Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." },
Do_not_emit_outputs: { code: 6010, category: DiagnosticCategory.Message, key: "Do not emit outputs." },
Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)" },
@@ -497,7 +498,7 @@ module ts {
Corrupted_locale_file_0: { code: 6051, category: DiagnosticCategory.Error, key: "Corrupted locale file {0}." },
Raise_error_on_expressions_and_declarations_with_an_implied_any_type: { code: 6052, category: DiagnosticCategory.Message, key: "Raise error on expressions and declarations with an implied 'any' type." },
File_0_not_found: { code: 6053, category: DiagnosticCategory.Error, key: "File '{0}' not found." },
File_0_must_have_extension_ts_or_d_ts: { code: 6054, category: DiagnosticCategory.Error, key: "File '{0}' must have extension '.ts' or '.d.ts'." },
File_0_has_unsupported_extension_The_only_supported_extensions_are_1: { code: 6054, category: DiagnosticCategory.Error, key: "File '{0}' has unsupported extension. The only supported extensions are {1}." },
Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: { code: 6055, category: DiagnosticCategory.Message, key: "Suppress noImplicitAny errors for indexing objects lacking index signatures." },
Do_not_emit_declarations_for_code_that_has_an_internal_annotation: { code: 6056, category: DiagnosticCategory.Message, key: "Do not emit declarations for code that has an '@internal' annotation." },
Preserve_new_lines_when_emitting_code: { code: 6057, category: DiagnosticCategory.Message, key: "Preserve new-lines when emitting code." },
+8 -4
View File
@@ -1444,6 +1444,10 @@
"category": "Error",
"code": 2502
},
"Cannot find namespace '{0}'.": {
"category": "Error",
"code": 2503
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -1761,11 +1765,11 @@
"category": "Error",
"code": 5033
},
"Option 'mapRoot' cannot be specified without specifying 'sourcemap' option.": {
"Option 'mapRoot' cannot be specified without specifying 'sourceMap' option.": {
"category": "Error",
"code": 5038
},
"Option 'sourceRoot' cannot be specified without specifying 'sourcemap' option.": {
"Option 'sourceRoot' cannot be specified without specifying 'sourceMap' option.": {
"category": "Error",
"code": 5039
},
@@ -1846,7 +1850,7 @@
"category": "Message",
"code": 6007
},
"Do not emit outputs if any type checking errors were reported.": {
"Do not emit outputs if any errors were reported.": {
"category": "Message",
"code": 6008
},
@@ -1978,7 +1982,7 @@
"category": "Error",
"code": 6053
},
"File '{0}' must have extension '.ts' or '.d.ts'.": {
"File '{0}' has unsupported extension. The only supported extensions are {1}.": {
"category": "Error",
"code": 6054
},
+83 -37
View File
@@ -139,7 +139,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
let exportEquals: ExportAssignment;
let hasExportStars: boolean;
/** write emitted output to disk*/
/** Write emitted output to disk */
let writeEmittedFiles = writeJavaScriptFile;
let detachedCommentsInfo: { nodePos: number; detachedCommentEndPos: number }[];
@@ -1366,7 +1366,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return true;
}
function emitListWithSpread(elements: Expression[], multiLine: boolean, trailingComma: boolean) {
function emitListWithSpread(elements: Expression[], alwaysCopy: boolean, multiLine: boolean, trailingComma: boolean) {
let pos = 0;
let group = 0;
let length = elements.length;
@@ -1383,6 +1383,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
e = (<SpreadElementExpression>e).expression;
emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e));
pos++;
if (pos === length && group === 0 && alwaysCopy && e.kind !== SyntaxKind.ArrayLiteralExpression) {
write(".slice()");
}
}
else {
let i = pos;
@@ -1422,7 +1425,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("]");
}
else {
emitListWithSpread(elements, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0,
emitListWithSpread(elements, /*alwaysCopy*/ true, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0,
/*trailingComma*/ elements.hasTrailingComma);
}
}
@@ -1847,7 +1850,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("void 0");
}
write(", ");
emitListWithSpread(node.arguments, /*multiLine*/ false, /*trailingComma*/ false);
emitListWithSpread(node.arguments, /*alwaysCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false);
write(")");
}
@@ -2639,7 +2642,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
writeLine();
emitStart(node);
if (compilerOptions.module === ModuleKind.System) {
// emit call to exporter only for top level nodes
if (compilerOptions.module === ModuleKind.System && node.parent === currentSourceFile) {
// emit export default <smth> as
// export("default", <smth>)
write(`${exportFunctionForFile}("`);
@@ -3055,13 +3059,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function emitVariableStatement(node: VariableStatement) {
let startIsEmitted = true;
if (!(node.flags & NodeFlags.Export)) {
startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
let startIsEmitted = false;
if (node.flags & NodeFlags.Export) {
if (isES6ExportedDeclaration(node)) {
// Exported ES6 module member
write("export ");
startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
}
}
else if (isES6ExportedDeclaration(node)) {
// Exported ES6 module member
write("export ");
else {
startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
}
if (startIsEmitted) {
@@ -3898,6 +3904,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitToken(SyntaxKind.CloseBraceToken, node.members.end);
scopeEmitEnd();
// TODO(rbuckton): Need to go back to `let _a = class C {}` approach, removing the defineProperty call for now.
// For a decorated class, we need to assign its name (if it has one). This is because we emit
// the class as a class expression to avoid the double-binding of the identifier:
//
@@ -3907,15 +3915,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
//
if (thisNodeIsDecorated) {
write(";");
if (node.name) {
writeLine();
write("Object.defineProperty(");
emitDeclarationName(node);
write(", \"name\", { value: \"");
emitDeclarationName(node);
write("\", configurable: true });");
writeLine();
}
}
// Emit static property assignment. Because classDeclaration is lexically evaluated,
@@ -4380,15 +4379,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return;
}
if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) {
emitStart(node);
if (isES6ExportedDeclaration(node)) {
write("export ");
if (!shouldHoistDeclarationInSystemJsModule(node)) {
// do not emit var if variable was already hoisted
if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) {
emitStart(node);
if (isES6ExportedDeclaration(node)) {
write("export ");
}
write("var ");
emit(node.name);
emitEnd(node);
write(";");
}
write("var ");
emit(node.name);
emitEnd(node);
write(";");
}
writeLine();
emitStart(node);
@@ -4410,7 +4412,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitModuleMemberName(node);
write(" = {}));");
emitEnd(node);
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export) {
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export && !shouldHoistDeclarationInSystemJsModule(node)) {
// do not emit var if variable was already hoisted
writeLine();
emitStart(node);
write("var ");
@@ -4421,6 +4424,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write(";");
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) {
// write the call to exporter for enum
writeLine();
write(`${exportFunctionForFile}("`);
emitDeclarationName(node);
write(`", `);
emitDeclarationName(node);
write(")");
}
emitExportMemberAssignments(node.name);
}
}
@@ -5101,7 +5113,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
// in theory we should hoist only exported functions and its dependencies
// in practice to simplify things we'll hoist all source level functions and variable declaration
// including variables declarations for module and class declarations
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration)[];
let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration | EnumDeclaration)[];
let hoistedFunctionDeclarations: FunctionDeclaration[];
let exportedDeclarations: (Identifier | Declaration)[];
@@ -5110,13 +5122,30 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
if (hoistedVars) {
writeLine();
write("var ");
let seen: Map<string> = {};
for (let i = 0; i < hoistedVars.length; ++i) {
let local = hoistedVars[i];
let name = local.kind === SyntaxKind.Identifier
? <Identifier>local
: <Identifier>(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local).name;
if (name) {
// do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables
let text = unescapeIdentifier(name.text);
if (hasProperty(seen, text)) {
continue;
}
else {
seen[text] = text;
}
}
if (i !== 0) {
write(", ");
}
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration) {
emitDeclarationName(<ClassDeclaration | ModuleDeclaration>local);
if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration || local.kind === SyntaxKind.EnumDeclaration) {
emitDeclarationName(<ClassDeclaration | ModuleDeclaration | EnumDeclaration>local);
}
else {
emit(local);
@@ -5150,6 +5179,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return exportedDeclarations;
function visit(node: Node): void {
if (node.flags & NodeFlags.Ambient) {
return;
}
if (node.kind === SyntaxKind.FunctionDeclaration) {
if (!hoistedFunctionDeclarations) {
hoistedFunctionDeclarations = [];
@@ -5160,7 +5193,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
if (node.kind === SyntaxKind.ClassDeclaration) {
// TODO: rename block scoped classes
if (!hoistedVars) {
hoistedVars = [];
}
@@ -5169,12 +5201,26 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return;
}
if (node.kind === SyntaxKind.ModuleDeclaration && shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
if (!hoistedVars) {
hoistedVars = [];
if (node.kind === SyntaxKind.EnumDeclaration) {
if (shouldEmitEnumDeclaration(<EnumDeclaration>node)) {
if (!hoistedVars) {
hoistedVars = [];
}
hoistedVars.push(<ModuleDeclaration>node);
}
hoistedVars.push(<ModuleDeclaration>node);
return;
}
if (node.kind === SyntaxKind.ModuleDeclaration) {
if (shouldEmitModuleDeclaration(<ModuleDeclaration>node)) {
if (!hoistedVars) {
hoistedVars = [];
}
hoistedVars.push(<ModuleDeclaration>node);
}
return;
}
+4 -9
View File
@@ -957,15 +957,6 @@ module ts {
}
function nextTokenCanFollowModifier() {
nextToken();
return canFollowModifier();
}
function parseAnyContextualModifier(): boolean {
return isModifier(token) && tryParse(nextTokenCanFollowContextualModifier);
}
function nextTokenCanFollowContextualModifier() {
if (token === SyntaxKind.ConstKeyword) {
// 'const' is only a modifier if followed by 'enum'.
return nextToken() === SyntaxKind.EnumKeyword;
@@ -984,6 +975,10 @@ module ts {
return canFollowModifier();
}
function parseAnyContextualModifier(): boolean {
return isModifier(token) && tryParse(nextTokenCanFollowModifier);
}
function canFollowModifier(): boolean {
return token === SyntaxKind.OpenBracketToken
|| token === SyntaxKind.OpenBraceToken
+27 -17
View File
@@ -8,7 +8,7 @@ module ts {
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
export const version = "1.5.0";
export const version = "1.5.2";
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
@@ -226,7 +226,12 @@ module ts {
// Create the emit resolver outside of the "emitTime" tracking code below. That way
// any cost associated with it (like type checking) are appropriate associated with
// the type-checking counter.
let emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile);
//
// If the -out option is specified, we should not pass the source file to getEmitResolver.
// This is because in the -out scenario all files need to be emitted, and therefore all
// files need to be type checked. And the way to specify that all files need to be type
// checked is to not pass the file to getEmitResolver.
let emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(options.out ? undefined : sourceFile);
let start = new Date().getTime();
@@ -240,7 +245,7 @@ module ts {
}
function getSourceFile(fileName: string) {
fileName = host.getCanonicalFileName(fileName);
fileName = host.getCanonicalFileName(normalizeSlashes(fileName));
return hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined;
}
@@ -314,45 +319,52 @@ module ts {
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
let start: number;
let length: number;
let extensions: string;
let diagnosticArgument: string[];
if (refEnd !== undefined && refPos !== undefined) {
start = refPos;
length = refEnd - refPos;
}
let diagnostic: DiagnosticMessage;
if (hasExtension(fileName)) {
if (!options.allowNonTsExtensions && !fileExtensionIs(host.getCanonicalFileName(fileName), ".ts")) {
diagnostic = Diagnostics.File_0_must_have_extension_ts_or_d_ts;
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
}
else if (!findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd)) {
diagnostic = Diagnostics.File_0_not_found;
diagnosticArgument = [fileName];
}
else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
diagnostic = Diagnostics.A_file_cannot_have_a_reference_to_itself;
diagnosticArgument = [fileName];
}
}
else {
if (options.allowNonTsExtensions && !findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd)) {
diagnostic = Diagnostics.File_0_not_found;
diagnosticArgument = [fileName];
}
else if (!findSourceFile(fileName + ".ts", isDefaultLib, refFile, refPos, refEnd) && !findSourceFile(fileName + ".d.ts", isDefaultLib, refFile, refPos, refEnd)) {
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, isDefaultLib, refFile, refPos, refEnd))) {
diagnostic = Diagnostics.File_0_not_found;
fileName += ".ts";
diagnosticArgument = [fileName];
}
}
if (diagnostic) {
if (refFile) {
diagnostics.add(createFileDiagnostic(refFile, start, length, diagnostic, fileName));
diagnostics.add(createFileDiagnostic(refFile, start, length, diagnostic, ...diagnosticArgument));
}
else {
diagnostics.add(createCompilerDiagnostic(diagnostic, fileName));
diagnostics.add(createCompilerDiagnostic(diagnostic, ...diagnosticArgument));
}
}
}
// Get source file from normalized fileName
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
let canonicalName = host.getCanonicalFileName(fileName);
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
if (hasProperty(filesByName, canonicalName)) {
// We've already looked for this file, use cached result
return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false);
@@ -424,9 +436,10 @@ module ts {
let moduleNameText = (<LiteralExpression>moduleNameExpr).text;
if (moduleNameText) {
let searchPath = basePath;
let searchName: string;
while (true) {
let searchName = normalizePath(combinePaths(searchPath, moduleNameText));
if (findModuleSourceFile(searchName + ".ts", moduleNameExpr) || findModuleSourceFile(searchName + ".d.ts", moduleNameExpr)) {
searchName = normalizePath(combinePaths(searchPath, moduleNameText));
if (forEach(supportedExtensions, extension => findModuleSourceFile(searchName + extension, moduleNameExpr))) {
break;
}
let parentPath = getDirectoryPath(searchPath);
@@ -455,10 +468,7 @@ module ts {
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
// only through top - level external module names. Relative external module names are not permitted.
let searchName = normalizePath(combinePaths(basePath, moduleName));
let tsFile = findModuleSourceFile(searchName + ".ts", nameLiteral);
if (!tsFile) {
findModuleSourceFile(searchName + ".d.ts", nameLiteral);
}
forEach(supportedExtensions, extension => findModuleSourceFile(searchName + extension, nameLiteral));
}
}
});
@@ -571,10 +581,10 @@ module ts {
if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
// Error to specify --mapRoot or --sourceRoot without mapSourceFiles
if (options.mapRoot) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_mapRoot_cannot_be_specified_without_specifying_sourceMap_option));
}
if (options.sourceRoot) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceRoot_cannot_be_specified_without_specifying_sourceMap_option));
}
return;
}
+12 -3
View File
@@ -484,9 +484,6 @@ module ts {
case SyntaxKind.IndexSignature:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.FunctionDeclaration:
return true;
}
}
@@ -1149,6 +1146,18 @@ module ts {
}
return false;
}
export function isParameterDeclaration(node: VariableLikeDeclaration) {
let root = getRootDeclaration(node);
return root.kind === SyntaxKind.Parameter;
}
export function getRootDeclaration(node: Node): Node {
while (node.kind === SyntaxKind.BindingElement) {
node = node.parent.parent;
}
return node;
}
export function nodeStartsNewLexicalEnvironment(n: Node): boolean {
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
+5 -5
View File
@@ -144,10 +144,10 @@ module FourSlash {
if (globalOptions.hasOwnProperty(prop)) {
switch (prop) {
case metadataOptionNames.allowNonTsExtensions:
settings.allowNonTsExtensions = true;
settings.allowNonTsExtensions = globalOptions[prop] === "true";
break;
case metadataOptionNames.declaration:
settings.declaration = true;
settings.declaration = globalOptions[prop] === "true";
break;
case metadataOptionNames.mapRoot:
settings.mapRoot = globalOptions[prop];
@@ -174,7 +174,7 @@ module FourSlash {
settings.outDir = globalOptions[prop];
break;
case metadataOptionNames.sourceMap:
settings.sourceMap = true;
settings.sourceMap = globalOptions[prop] === "true";
break;
case metadataOptionNames.sourceRoot:
settings.sourceRoot = globalOptions[prop];
@@ -308,7 +308,7 @@ module FourSlash {
ts.forEach(testData.files, file => {
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
this.inputFiles[file.fileName] = file.content;
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference]) {
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference] === "true") {
startResolveFileRef = file;
} else if (startResolveFileRef) {
// If entry point for resolving file references is already specified, report duplication error
@@ -1159,7 +1159,7 @@ module FourSlash {
var allFourSlashFiles = this.testData.files;
for (var idx = 0; idx < allFourSlashFiles.length; ++idx) {
var file = allFourSlashFiles[idx];
if (file.fileOptions[metadataOptionNames.emitThisFile]) {
if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") {
// Find a file with the flag emitThisFile turned on
emitFiles.push(file);
}
+2 -2
View File
@@ -35,9 +35,9 @@ class FourSlashRunner extends RunnerBase {
this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false });
}
describe(this.testSuiteName, () => {
this.tests.forEach((fn: string) => {
fn = ts.normalizeSlashes(fn);
describe(fn, () => {
fn = ts.normalizeSlashes(fn);
var justName = fn.replace(/^.*[\\\/]/, '');
// Convert to relative path
+14 -11
View File
@@ -45,11 +45,13 @@ module Utils {
export function getExecutionEnvironment() {
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
return ExecutionEnvironment.CScript;
} else if (process && process.execPath && process.execPath.indexOf("node") !== -1) {
return ExecutionEnvironment.Node;
} else {
}
else if (typeof window !== "undefined") {
return ExecutionEnvironment.Browser;
}
else {
return ExecutionEnvironment.Node;
}
}
export var currentExecutionEnvironment = getExecutionEnvironment();
@@ -946,6 +948,7 @@ module Harness {
options = options || { noResolve: false };
options.target = options.target || ts.ScriptTarget.ES3;
options.module = options.module || ts.ModuleKind.None;
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
options.noErrorTruncation = true;
if (lightMode) {
options.noLibCheck = true;
@@ -1044,19 +1047,19 @@ module Harness {
break;
case 'noemitonerror':
options.noEmitOnError = !!setting.value;
options.noEmitOnError = setting.value === 'true';
break;
case 'noresolve':
options.noResolve = !!setting.value;
options.noResolve = setting.value === 'true';
break;
case 'noimplicitany':
options.noImplicitAny = !!setting.value;
options.noImplicitAny = setting.value === 'true';
break;
case 'nolib':
options.noLib = !!setting.value;
options.noLib = setting.value === 'true';
break;
case 'out':
@@ -1078,11 +1081,11 @@ module Harness {
break;
case 'sourcemap':
options.sourceMap = !!setting.value;
options.sourceMap = setting.value === 'true';
break;
case 'declaration':
options.declaration = !!setting.value;
options.declaration = setting.value === 'true';
break;
case 'newline':
@@ -1106,7 +1109,7 @@ module Harness {
break;
case 'stripinternal':
options.stripInternal = !!setting.value;
options.stripInternal = setting.value === 'true';
case 'usecasesensitivefilenames':
useCaseSensitiveFileNames = setting.value === 'true';
@@ -1117,7 +1120,7 @@ module Harness {
break;
case 'emitbom':
options.emitBOM = !!setting.value;
options.emitBOM = setting.value === 'true';
break;
case 'errortruncation':
+2
View File
@@ -3580,6 +3580,7 @@ interface PromiseLike<T> {
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
}
/**
@@ -3593,6 +3594,7 @@ interface Promise<T> {
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
/**
* Attaches a callback for only the rejection of the Promise.
+26 -26
View File
@@ -398,7 +398,7 @@ module ts.server {
export class ProjectService {
filenameToScriptInfo: ts.Map<ScriptInfo> = {};
// open, non-configured root files
// open, non-configured root files
openFileRoots: ScriptInfo[] = [];
// projects built from openFileRoots
inferredProjects: Project[] = [];
@@ -421,7 +421,7 @@ module ts.server {
hostInfo: "Unknown host"
}
}
getFormatCodeOptions(file?: string) {
if (file) {
var info = this.filenameToScriptInfo[file];
@@ -448,7 +448,7 @@ module ts.server {
}
}
}
log(msg: string, type = "Err") {
this.psLogger.msg(msg, type);
}
@@ -457,17 +457,17 @@ module ts.server {
if (args.file) {
var info = this.filenameToScriptInfo[args.file];
if (info) {
info.setFormatOptions(args.formatOptions);
info.setFormatOptions(args.formatOptions);
this.log("Host configuration update for file " + args.file, "Info");
}
}
else {
if (args.hostInfo !== undefined) {
this.hostConfiguration.hostInfo = args.hostInfo;
this.log("Host information " + args.hostInfo, "Info");
this.log("Host information " + args.hostInfo, "Info");
}
if (args.formatOptions) {
mergeFormatOptions(this.hostConfiguration.formatCodeOptions, args.formatOptions);
mergeFormatOptions(this.hostConfiguration.formatCodeOptions, args.formatOptions);
this.log("Format host information updated", "Info");
}
}
@@ -487,7 +487,7 @@ module ts.server {
fileDeletedInFilesystem(info: ScriptInfo) {
this.psLogger.info(info.fileName + " deleted");
if (info.fileWatcher) {
info.fileWatcher.close();
info.fileWatcher = undefined;
@@ -537,7 +537,7 @@ module ts.server {
}
return false;
}
addOpenFile(info: ScriptInfo) {
if (this.setConfiguredProjectRoot(info)) {
this.openFileRootsConfigured.push(info);
@@ -561,7 +561,7 @@ module ts.server {
copyListRemovingItem(r.defaultProject, this.inferredProjects);
// put r in referenced open file list
this.openFilesReferenced.push(r);
// set default project of r to the new project
// set default project of r to the new project
r.defaultProject = info.defaultProject;
}
else {
@@ -694,7 +694,7 @@ module ts.server {
this.openFilesReferenced = openFilesReferenced;
// Then, loop through all of the open files that are project roots.
// For each root file, note the project that it roots. Then see if
// For each root file, note the project that it roots. Then see if
// any other projects newly reference the file. If zero projects
// newly reference the file, keep it as a root. If one or more
// projects newly references the file, remove its project from the
@@ -719,7 +719,7 @@ module ts.server {
// Finally, if we found any open, referenced files that are no longer
// referenced by their default project, treat them as newly opened
// by the editor.
// by the editor.
for (var i = 0, len = unattachedOpenFiles.length; i < len; i++) {
this.addOpenFile(unattachedOpenFiles[i]);
}
@@ -809,7 +809,7 @@ module ts.server {
}
else {
this.log("Opened configuration file " + configFileName,"Info");
this.configuredProjects.push(configResult.project);
this.configuredProjects.push(configResult.project);
}
}
var info = this.openFile(fileName, true);
@@ -901,22 +901,22 @@ module ts.server {
}
return false;
}
openConfigFile(configFilename: string, clientFileName?: string): ProjectOpenResult {
configFilename = ts.normalizePath(configFilename);
// file references will be relative to dirPath (or absolute)
var dirPath = ts.getDirectoryPath(configFilename);
var rawConfig = <ProjectOptions>ts.readConfigFile(configFilename);
if (!rawConfig) {
return { errorMsg: "tsconfig syntax error" };
var rawConfig: { config?: ProjectOptions; error?: Diagnostic; } = ts.readConfigFile(configFilename);
if (rawConfig.error) {
return rawConfig.error;
}
else {
var parsedCommandLine = ts.parseConfigFile(rawConfig, ts.sys, dirPath);
var parsedCommandLine = ts.parseConfigFile(rawConfig.config, ts.sys, dirPath);
if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) {
return { errorMsg: "tsconfig option errors" };
}
else if (parsedCommandLine.fileNames) {
var projectOptions: ProjectOptions = {
var projectOptions: ProjectOptions = {
files: parsedCommandLine.fileNames,
compilerOptions: parsedCommandLine.options
};
@@ -1040,7 +1040,7 @@ module ts.server {
startPath: LineCollection[];
endBranch: LineCollection[] = [];
branchNode: LineNode;
// path to current node
// path to current node
stack: LineNode[];
state = CharRangeSection.Entire;
lineCollectionAtBranch: LineCollection;
@@ -1242,7 +1242,7 @@ module ts.server {
}
}
// text change information
// text change information
class TextChange {
constructor(public pos: number, public deleteLen: number, public insertedText?: string) {
}
@@ -1290,7 +1290,7 @@ module ts.server {
if (cb)
cb();
}
// reload whole script, leaving no change history behind reload
reload(script: string) {
this.currentVersion++;
@@ -1300,7 +1300,7 @@ module ts.server {
snap.index = new LineIndex();
var lm = LineIndex.linesFromText(script);
snap.index.load(lm.lines);
// REVIEW: could use linked list
// REVIEW: could use linked list
for (var i = this.minVersion; i < this.currentVersion; i++) {
this.versions[i] = undefined;
}
@@ -1381,7 +1381,7 @@ module ts.server {
return this.index.root.charCount();
}
// this requires linear space so don't hold on to these
// this requires linear space so don't hold on to these
getLineStartPositions(): number[] {
var starts: number[] = [-1];
var count = 1;
@@ -1643,7 +1643,7 @@ module ts.server {
}
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
// assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars)
// assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars)
var childIndex = 0;
var child = this.children[0];
var childCharCount = child.charCount();
@@ -1729,7 +1729,7 @@ module ts.server {
line: lineNumber,
offset: charOffset
}
}
}
else if (childInfo.child.isLeaf()) {
return {
line: lineNumber,
@@ -1917,4 +1917,4 @@ module ts.server {
return 1;
}
}
}
}
+78 -51
View File
@@ -949,6 +949,7 @@ module ts {
export interface LanguageServiceHost {
getCompilationSettings(): CompilerOptions;
getNewLine?(): string;
getProjectVersion?(): string;
getScriptFileNames(): string[];
getScriptVersion(fileName: string): string;
getScriptSnapshot(fileName: string): IScriptSnapshot;
@@ -1632,7 +1633,7 @@ module ts {
private fileNameToEntry: Map<HostFileInformation>;
private _compilationSettings: CompilerOptions;
constructor(private host: LanguageServiceHost) {
constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) {
// script id => script index
this.fileNameToEntry = {};
@@ -1650,6 +1651,10 @@ module ts {
return this._compilationSettings;
}
private normalizeFileName(fileName: string): string {
return this.getCanonicalFileName(normalizeSlashes(fileName));
}
private createEntry(fileName: string) {
let entry: HostFileInformation;
let scriptSnapshot = this.host.getScriptSnapshot(fileName);
@@ -1661,15 +1666,15 @@ module ts {
};
}
return this.fileNameToEntry[normalizeSlashes(fileName)] = entry;
return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry;
}
public getEntry(fileName: string): HostFileInformation {
return lookUp(this.fileNameToEntry, normalizeSlashes(fileName));
private getEntry(fileName: string): HostFileInformation {
return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName));
}
public contains(fileName: string): boolean {
return hasProperty(this.fileNameToEntry, normalizeSlashes(fileName));
private contains(fileName: string): boolean {
return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName));
}
public getOrCreateEntry(fileName: string): HostFileInformation {
@@ -1684,8 +1689,10 @@ module ts {
let fileNames: string[] = [];
forEachKey(this.fileNameToEntry, key => {
if (hasProperty(this.fileNameToEntry, key) && this.fileNameToEntry[key])
fileNames.push(key);
let entry = this.getEntry(key);
if (entry) {
fileNames.push(entry.hostFileName);
}
});
return fileNames;
@@ -2347,6 +2354,7 @@ module ts {
let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host);
let ruleProvider: formatting.RulesProvider;
let program: Program;
let lastProjectVersion: string;
let useCaseSensitivefileNames = false;
let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
@@ -2386,8 +2394,20 @@ module ts {
}
function synchronizeHostData(): void {
// perform fast check if host supports it
if (host.getProjectVersion) {
let hostProjectVersion = host.getProjectVersion();
if (hostProjectVersion) {
if (lastProjectVersion === hostProjectVersion) {
return;
}
lastProjectVersion = hostProjectVersion;
}
}
// Get a fresh cache of the host information
let hostCache = new HostCache(host);
let hostCache = new HostCache(host, getCanonicalFileName);
// If the program is already up-to-date, we can reuse it
if (programUpToDate()) {
@@ -2408,7 +2428,7 @@ module ts {
let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, {
getSourceFile: getOrCreateSourceFile,
getCancellationToken: () => cancellationToken,
getCanonicalFileName: (fileName) => useCaseSensitivefileNames ? fileName : fileName.toLowerCase(),
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitivefileNames,
getNewLine: () => host.getNewLine ? host.getNewLine() : "\r\n",
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
@@ -3019,46 +3039,47 @@ module ts {
let containingNodeKind = previousToken.parent.kind;
switch (previousToken.kind) {
case SyntaxKind.CommaToken:
return containingNodeKind === SyntaxKind.CallExpression // func( a, |
|| containingNodeKind === SyntaxKind.Constructor // constructor( a, | public, protected, private keywords are allowed here, so show completion
|| containingNodeKind === SyntaxKind.NewExpression // new C(a, |
|| containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, |
|| containingNodeKind === SyntaxKind.BinaryExpression; // let x = (a, |
return containingNodeKind === SyntaxKind.CallExpression // func( a, |
|| containingNodeKind === SyntaxKind.Constructor // constructor( a, | public, protected, private keywords are allowed here, so show completion
|| containingNodeKind === SyntaxKind.NewExpression // new C(a, |
|| containingNodeKind === SyntaxKind.ArrayLiteralExpression // [a, |
|| containingNodeKind === SyntaxKind.BinaryExpression // let x = (a, |
|| containingNodeKind === SyntaxKind.FunctionType; // var x: (s: string, list|
case SyntaxKind.OpenParenToken:
return containingNodeKind === SyntaxKind.CallExpression // func( |
|| containingNodeKind === SyntaxKind.Constructor // constructor( |
|| containingNodeKind === SyntaxKind.NewExpression // new C(a|
|| containingNodeKind === SyntaxKind.ParenthesizedExpression; // let x = (a|
|| containingNodeKind === SyntaxKind.ParenthesizedExpression // let x = (a|
|| containingNodeKind === SyntaxKind.ParenthesizedType; // function F(pred: (a| this can become an arrow function, where 'a' is the argument
case SyntaxKind.OpenBracketToken:
return containingNodeKind === SyntaxKind.ArrayLiteralExpression; // [ |
return containingNodeKind === SyntaxKind.ArrayLiteralExpression; // [ |
case SyntaxKind.ModuleKeyword: // module |
case SyntaxKind.NamespaceKeyword: // namespace |
case SyntaxKind.ModuleKeyword: // module |
case SyntaxKind.NamespaceKeyword: // namespace |
return true;
case SyntaxKind.DotToken:
return containingNodeKind === SyntaxKind.ModuleDeclaration; // module A.|
return containingNodeKind === SyntaxKind.ModuleDeclaration; // module A.|
case SyntaxKind.OpenBraceToken:
return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ |
return containingNodeKind === SyntaxKind.ClassDeclaration; // class A{ |
case SyntaxKind.EqualsToken:
return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a|
|| containingNodeKind === SyntaxKind.BinaryExpression; // x = a|
return containingNodeKind === SyntaxKind.VariableDeclaration // let x = a|
|| containingNodeKind === SyntaxKind.BinaryExpression; // x = a|
case SyntaxKind.TemplateHead:
return containingNodeKind === SyntaxKind.TemplateExpression; // `aa ${|
return containingNodeKind === SyntaxKind.TemplateExpression; // `aa ${|
case SyntaxKind.TemplateMiddle:
return containingNodeKind === SyntaxKind.TemplateSpan; // `aa ${10} dd ${|
return containingNodeKind === SyntaxKind.TemplateSpan; // `aa ${10} dd ${|
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
return containingNodeKind === SyntaxKind.PropertyDeclaration; // class A{ public |
return containingNodeKind === SyntaxKind.PropertyDeclaration; // class A{ public |
}
// Previous token may have been a keyword that was converted to an identifier.
@@ -3137,40 +3158,43 @@ module ts {
return containingNodeKind === SyntaxKind.VariableDeclaration ||
containingNodeKind === SyntaxKind.VariableDeclarationList ||
containingNodeKind === SyntaxKind.VariableStatement ||
containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, |
containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, |
isFunction(containingNodeKind) ||
containingNodeKind === SyntaxKind.ClassDeclaration || // class A<T, |
containingNodeKind === SyntaxKind.FunctionDeclaration || // function A<T, |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A<T, |
containingNodeKind === SyntaxKind.ArrayBindingPattern || // var [x, y|
containingNodeKind === SyntaxKind.ObjectBindingPattern; // function func({ x, y|
containingNodeKind === SyntaxKind.ClassDeclaration || // class A<T, |
containingNodeKind === SyntaxKind.FunctionDeclaration || // function A<T, |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A<T, |
containingNodeKind === SyntaxKind.ArrayBindingPattern || // var [x, y|
containingNodeKind === SyntaxKind.ObjectBindingPattern; // function func({ x, y|
case SyntaxKind.DotToken:
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [.|
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [.|
case SyntaxKind.ColonToken:
return containingNodeKind === SyntaxKind.BindingElement; // var {x :html|
case SyntaxKind.OpenBracketToken:
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [x|
return containingNodeKind === SyntaxKind.ArrayBindingPattern; // var [x|
case SyntaxKind.OpenParenToken:
return containingNodeKind === SyntaxKind.CatchClause ||
isFunction(containingNodeKind);
case SyntaxKind.OpenBraceToken:
return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { |
containingNodeKind === SyntaxKind.TypeLiteral || // let x : { |
containingNodeKind === SyntaxKind.ObjectBindingPattern; // function func({ x|
return containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface a { |
containingNodeKind === SyntaxKind.TypeLiteral || // let x : { |
containingNodeKind === SyntaxKind.ObjectBindingPattern; // function func({ x|
case SyntaxKind.SemicolonToken:
return containingNodeKind === SyntaxKind.PropertySignature &&
previousToken.parent && previousToken.parent.parent &&
(previousToken.parent.parent.kind === SyntaxKind.InterfaceDeclaration || // interface a { f; |
previousToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; |
previousToken.parent.parent.kind === SyntaxKind.TypeLiteral); // let x : { a; |
case SyntaxKind.LessThanToken:
return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< |
containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< |
return containingNodeKind === SyntaxKind.ClassDeclaration || // class A< |
containingNodeKind === SyntaxKind.FunctionDeclaration || // function A< |
containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A< |
isFunction(containingNodeKind);
case SyntaxKind.StaticKeyword:
@@ -3180,7 +3204,7 @@ module ts {
return containingNodeKind === SyntaxKind.Parameter ||
containingNodeKind === SyntaxKind.Constructor ||
(previousToken.parent && previousToken.parent.parent &&
previousToken.parent.parent.kind === SyntaxKind.ArrayBindingPattern); // var [ ...z|
previousToken.parent.parent.kind === SyntaxKind.ArrayBindingPattern); // var [...z|
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
@@ -3198,6 +3222,7 @@ module ts {
case SyntaxKind.LetKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.YieldKeyword:
case SyntaxKind.TypeKeyword: // type htm|
return true;
}
@@ -6033,11 +6058,13 @@ module ts {
let end = triviaScanner.getTextPos();
let width = end - start;
if (textSpanIntersectsWith(span, start, width)) {
if (!isTrivia(kind)) {
return;
}
// The moment we get something that isn't trivia, then stop processing.
if (!isTrivia(kind)) {
return;
}
// Only bother with the trivia if it at least intersects the span of interest.
if (textSpanIntersectsWith(span, start, width)) {
if (isComment(kind)) {
// Simple comment. Just add as is.
pushClassification(start, width, ClassificationType.comment);
+22 -12
View File
@@ -1,6 +1,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -55,6 +55,7 @@ module ts {
getCurrentDirectory(): string;
getDefaultLibFileName(options: string): string;
getNewLine?(): string;
getProjectVersion?(): string;
}
/** Public interface of the the of a config service shim instance.*/
@@ -83,7 +84,7 @@ module ts {
export interface Shim {
dispose(dummy: any): void;
}
export interface LanguageServiceShim extends Shim {
languageService: LanguageService;
@@ -145,7 +146,7 @@ module ts {
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
*/
getReferencesAtPosition(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
* { definition: <encoded>; references: <encoded>[] }[]
@@ -162,8 +163,8 @@ module ts {
/**
* Returns a JSON-encoded value of the type:
* { fileName: string; highlights: { start: number; length: number, isDefinition: boolean }[] }[]
*
* @param fileToSearch A JSON encoded string[] containing the file names that should be
*
* @param fileToSearch A JSON encoded string[] containing the file names that should be
* considered when searching.
*/
getDocumentHighlights(fileName: string, position: number, filesToSearch: string): string;
@@ -244,7 +245,7 @@ module ts {
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
private files: string[];
constructor(private shimHost: LanguageServiceShimHost) {
}
@@ -255,11 +256,20 @@ module ts {
public trace(s: string): void {
this.shimHost.trace(s);
}
public error(s: string): void {
this.shimHost.error(s);
}
public getProjectVersion(): string {
if (!this.shimHost.getProjectVersion) {
// shimmed host does not support getProjectVersion
return undefined;
}
return this.shimHost.getProjectVersion();
}
public getCompilationSettings(): CompilerOptions {
var settingsJson = this.shimHost.getCompilationSettings();
if (settingsJson == null || settingsJson == "") {
@@ -322,7 +332,7 @@ module ts {
}
}
}
export class CoreServicesShimHostAdapter implements ParseConfigHost {
constructor(private shimHost: CoreServicesShimHost) {
@@ -587,7 +597,7 @@ module ts {
/**
* Computes the definition location and file for the symbol
* at the requested position.
* at the requested position.
*/
public getDefinitionAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
@@ -601,7 +611,7 @@ module ts {
/**
* Computes the definition location of the type of the symbol
* at the requested position.
* at the requested position.
*/
public getTypeDefinitionAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
@@ -684,8 +694,8 @@ module ts {
/// COMPLETION LISTS
/**
* Get a string based representation of the completions
* to provide at the given source position and providing a member completion
* Get a string based representation of the completions
* to provide at the given source position and providing a member completion
* list if requested.
*/
public getCompletionsAtPosition(fileName: string, position: number) {