mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
merge with master
This commit is contained in:
+81
-36
@@ -31,13 +31,14 @@ module ts {
|
||||
|
||||
var parent: Node;
|
||||
var container: Declaration;
|
||||
var blockScopeContainer: Node;
|
||||
var lastContainer: Declaration;
|
||||
var symbolCount = 0;
|
||||
var Symbol = objectAllocator.getSymbolConstructor();
|
||||
|
||||
if (!file.locals) {
|
||||
file.locals = {};
|
||||
container = file;
|
||||
container = blockScopeContainer = file;
|
||||
bind(file);
|
||||
file.symbolCount = symbolCount;
|
||||
}
|
||||
@@ -86,10 +87,11 @@ module ts {
|
||||
}
|
||||
// Report errors every position with duplicate declaration
|
||||
// Report errors on previous encountered declarations
|
||||
var message = symbol.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0;
|
||||
forEach(symbol.declarations, (declaration) => {
|
||||
file.semanticErrors.push(createDiagnosticForNode(declaration.name, Diagnostics.Duplicate_identifier_0, getDisplayName(declaration)));
|
||||
file.semanticErrors.push(createDiagnosticForNode(declaration.name, message, getDisplayName(declaration)));
|
||||
});
|
||||
file.semanticErrors.push(createDiagnosticForNode(node.name, Diagnostics.Duplicate_identifier_0, getDisplayName(node)));
|
||||
file.semanticErrors.push(createDiagnosticForNode(node.name, message, getDisplayName(node)));
|
||||
|
||||
symbol = createSymbol(0, name);
|
||||
}
|
||||
@@ -167,12 +169,13 @@ module ts {
|
||||
|
||||
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
|
||||
// in the type checker to validate that the local name used for a container is unique.
|
||||
function bindChildren(node: Declaration, symbolKind: SymbolFlags) {
|
||||
function bindChildren(node: Declaration, symbolKind: SymbolFlags, isBlockScopeContainer: boolean) {
|
||||
if (symbolKind & SymbolFlags.HasLocals) {
|
||||
node.locals = {};
|
||||
}
|
||||
var saveParent = parent;
|
||||
var saveContainer = container;
|
||||
var savedBlockScopeContainer = blockScopeContainer;
|
||||
parent = node;
|
||||
if (symbolKind & SymbolFlags.IsContainer) {
|
||||
container = node;
|
||||
@@ -184,12 +187,16 @@ module ts {
|
||||
lastContainer = container;
|
||||
}
|
||||
}
|
||||
if (isBlockScopeContainer) {
|
||||
blockScopeContainer = node;
|
||||
}
|
||||
forEachChild(node, bind);
|
||||
container = saveContainer;
|
||||
parent = saveParent;
|
||||
blockScopeContainer = savedBlockScopeContainer;
|
||||
}
|
||||
|
||||
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) {
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
declareModuleMember(node, symbolKind, symbolExcludes);
|
||||
@@ -225,121 +232,159 @@ module ts {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
}
|
||||
bindChildren(node, symbolKind);
|
||||
bindChildren(node, symbolKind, isBlockScopeContainer);
|
||||
}
|
||||
|
||||
function bindConstructorDeclaration(node: ConstructorDeclaration) {
|
||||
bindDeclaration(node, SymbolFlags.Constructor, 0);
|
||||
bindDeclaration(node, SymbolFlags.Constructor, 0, /*isBlockScopeContainer*/ true);
|
||||
forEach(node.parameters, p => {
|
||||
if (p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) {
|
||||
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindModuleDeclaration(node: ModuleDeclaration) {
|
||||
if (node.name.kind === SyntaxKind.StringLiteral) {
|
||||
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
||||
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
|
||||
}
|
||||
else if (isInstantiated(node)) {
|
||||
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
||||
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
|
||||
}
|
||||
else {
|
||||
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
|
||||
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) {
|
||||
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) {
|
||||
var symbol = createSymbol(symbolKind, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolKind);
|
||||
bindChildren(node, symbolKind);
|
||||
bindChildren(node, symbolKind, isBlockScopeContainer);
|
||||
}
|
||||
|
||||
function bindCatchVariableDeclaration(node: CatchBlock) {
|
||||
var symbol = createSymbol(SymbolFlags.Variable, node.variable.text || "__missing");
|
||||
addDeclarationToSymbol(symbol, node, SymbolFlags.Variable);
|
||||
var symbol = createSymbol(SymbolFlags.FunctionScopedVariable, node.variable.text || "__missing");
|
||||
addDeclarationToSymbol(symbol, node, SymbolFlags.FunctionScopedVariable);
|
||||
var saveParent = parent;
|
||||
parent = node;
|
||||
var savedBlockScopeContainer = blockScopeContainer;
|
||||
parent = blockScopeContainer = node;
|
||||
forEachChild(node, bind);
|
||||
parent = saveParent;
|
||||
blockScopeContainer = savedBlockScopeContainer;
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
switch (blockScopeContainer.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>container)) {
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = {};
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
|
||||
function bind(node: Node) {
|
||||
node.parent = parent;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeParameter:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.VariableExcludes);
|
||||
if (node.flags & NodeFlags.BlockScoped) {
|
||||
bindBlockScopedVariableDeclaration(<Declaration>node);
|
||||
}
|
||||
else {
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Property:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.EnumMember:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.CallSignature:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.Method:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.ConstructSignature:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.IndexSignature:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.Constructor:
|
||||
bindConstructorDeclaration(<ConstructorDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.GetAccessor:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.SetAccessor:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.TypeLiteral:
|
||||
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type");
|
||||
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object", /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Function, "__function");
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.CatchBlock:
|
||||
bindCatchVariableDeclaration(<CatchBlock>node);
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
bindModuleDeclaration(<ModuleDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes);
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>node)) {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"');
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).filename) + '"', /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
}
|
||||
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.TryBlock:
|
||||
case SyntaxKind.CatchBlock:
|
||||
case SyntaxKind.FinallyBlock:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
bindChildren(node, 0 , true);
|
||||
break;
|
||||
|
||||
default:
|
||||
var saveParent = parent;
|
||||
parent = node;
|
||||
|
||||
+813
-697
File diff suppressed because it is too large
Load Diff
@@ -102,10 +102,10 @@ module ts {
|
||||
{
|
||||
name: "target",
|
||||
shortName: "t",
|
||||
type: { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5 },
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5,
|
||||
type: { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5 , "es6": ScriptTarget.ES6 },
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental,
|
||||
paramType: Diagnostics.VERSION,
|
||||
error: Diagnostics.Argument_for_target_option_must_be_es3_or_es5
|
||||
error: Diagnostics.Argument_for_target_option_must_be_es3_es5_or_es6
|
||||
},
|
||||
{
|
||||
name: "version",
|
||||
|
||||
@@ -232,7 +232,8 @@ module ts {
|
||||
|
||||
messageText: text,
|
||||
category: message.category,
|
||||
code: message.code
|
||||
code: message.code,
|
||||
isEarly: message.isEarly
|
||||
};
|
||||
}
|
||||
|
||||
@@ -251,7 +252,8 @@ module ts {
|
||||
|
||||
messageText: text,
|
||||
category: message.category,
|
||||
code: message.code
|
||||
code: message.code,
|
||||
isEarly: message.isEarly
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,12 @@ 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." },
|
||||
var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." },
|
||||
let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." },
|
||||
const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." },
|
||||
const_declarations_must_be_initialized: { code: 1155, category: DiagnosticCategory.Error, key: "'const' declarations must be initialized" },
|
||||
const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations can only be declared inside a block." },
|
||||
let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." },
|
||||
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." },
|
||||
@@ -261,6 +266,11 @@ module ts {
|
||||
Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." },
|
||||
Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." },
|
||||
The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." },
|
||||
Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration.", isEarly: true },
|
||||
The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator cannot be a constant.", isEarly: true },
|
||||
Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: DiagnosticCategory.Error, key: "Left-hand side of assignment expression cannot be a constant.", isEarly: true },
|
||||
Cannot_redeclare_block_scoped_variable_0: { code: 2451, category: DiagnosticCategory.Error, key: "Cannot redeclare block-scoped variable '{0}'.", isEarly: true },
|
||||
An_enum_member_cannot_have_a_numeric_name: { code: 2452, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." },
|
||||
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_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." },
|
||||
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}'." },
|
||||
@@ -355,7 +365,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_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." },
|
||||
Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), or 'ES5'" },
|
||||
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)" },
|
||||
Specify_module_code_generation_Colon_commonjs_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs' or 'amd'" },
|
||||
Print_this_message: { code: 6017, category: DiagnosticCategory.Message, key: "Print this message." },
|
||||
Print_the_compiler_s_version: { code: 6019, category: DiagnosticCategory.Message, key: "Print the compiler's version." },
|
||||
@@ -377,7 +387,7 @@ module ts {
|
||||
Compiler_option_0_expects_an_argument: { code: 6044, category: DiagnosticCategory.Error, key: "Compiler option '{0}' expects an argument." },
|
||||
Unterminated_quoted_string_in_response_file_0: { code: 6045, category: DiagnosticCategory.Error, key: "Unterminated quoted string in response file '{0}'." },
|
||||
Argument_for_module_option_must_be_commonjs_or_amd: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs' or 'amd'." },
|
||||
Argument_for_target_option_must_be_es3_or_es5: { code: 6047, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'es3' or 'es5'." },
|
||||
Argument_for_target_option_must_be_es3_es5_or_es6: { code: 6047, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'es3', 'es5', or 'es6'." },
|
||||
Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: 6048, category: DiagnosticCategory.Error, key: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'." },
|
||||
Unsupported_locale_0: { code: 6049, category: DiagnosticCategory.Error, key: "Unsupported locale '{0}'." },
|
||||
Unable_to_open_file_0: { code: 6050, category: DiagnosticCategory.Error, key: "Unable to open file '{0}'." },
|
||||
|
||||
@@ -447,9 +447,29 @@
|
||||
"category": "Error",
|
||||
"code": 1150
|
||||
},
|
||||
"An enum member cannot have a numeric name.": {
|
||||
"'var', 'let' or 'const' expected.": {
|
||||
"category": "Error",
|
||||
"code": 1151
|
||||
"code": 1152
|
||||
},
|
||||
"'let' declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"category": "Error",
|
||||
"code": 1153
|
||||
},
|
||||
"'const' declarations are only available when targeting ECMAScript 6 and higher.": {
|
||||
"category": "Error",
|
||||
"code": 1154
|
||||
},
|
||||
"'const' declarations must be initialized": {
|
||||
"category": "Error",
|
||||
"code": 1155
|
||||
},
|
||||
"'const' declarations can only be declared inside a block.": {
|
||||
"category": "Error",
|
||||
"code": 1156
|
||||
},
|
||||
"'let' declarations can only be declared inside a block.": {
|
||||
"category": "Error",
|
||||
"code": 1157
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
@@ -1036,6 +1056,30 @@
|
||||
"category": "Error",
|
||||
"code": 2447
|
||||
},
|
||||
"Block-scoped variable '{0}' used before its declaration.": {
|
||||
"category": "Error",
|
||||
"code": 2448,
|
||||
"isEarly": true
|
||||
},
|
||||
"The operand of an increment or decrement operator cannot be a constant.": {
|
||||
"category": "Error",
|
||||
"code": 2449,
|
||||
"isEarly": true
|
||||
},
|
||||
"Left-hand side of assignment expression cannot be a constant.": {
|
||||
"category": "Error",
|
||||
"code": 2450,
|
||||
"isEarly": true
|
||||
},
|
||||
"Cannot redeclare block-scoped variable '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2451,
|
||||
"isEarly": true
|
||||
},
|
||||
"An enum member cannot have a numeric name.": {
|
||||
"category": "Error",
|
||||
"code": 2452
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -1416,7 +1460,7 @@
|
||||
"category": "Message",
|
||||
"code": 6009
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), or 'ES5'": {
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
@@ -1504,7 +1548,7 @@
|
||||
"category": "Error",
|
||||
"code": 6046
|
||||
},
|
||||
"Argument for '--target' option must be 'es3' or 'es5'.": {
|
||||
"Argument for '--target' option must be 'es3', 'es5', or 'es6'.": {
|
||||
"category": "Error",
|
||||
"code": 6047
|
||||
},
|
||||
|
||||
+70
-27
@@ -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) {
|
||||
@@ -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
|
||||
|
||||
@@ -1149,7 +1143,15 @@ module ts {
|
||||
write(" ");
|
||||
endPos = emitToken(SyntaxKind.OpenParenToken, endPos);
|
||||
if (node.declarations) {
|
||||
emitToken(SyntaxKind.VarKeyword, endPos);
|
||||
if (node.declarations[0] && node.declarations[0].flags & NodeFlags.Let) {
|
||||
emitToken(SyntaxKind.LetKeyword, endPos);
|
||||
}
|
||||
else if (node.declarations[0] && node.declarations[0].flags & NodeFlags.Const) {
|
||||
emitToken(SyntaxKind.ConstKeyword, endPos);
|
||||
}
|
||||
else {
|
||||
emitToken(SyntaxKind.VarKeyword, endPos);
|
||||
}
|
||||
write(" ");
|
||||
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
|
||||
}
|
||||
@@ -1169,7 +1171,12 @@ module ts {
|
||||
write(" ");
|
||||
endPos = emitToken(SyntaxKind.OpenParenToken, endPos);
|
||||
if (node.declaration) {
|
||||
emitToken(SyntaxKind.VarKeyword, endPos);
|
||||
if (node.declaration.flags & NodeFlags.Let) {
|
||||
emitToken(SyntaxKind.LetKeyword, endPos);
|
||||
}
|
||||
else {
|
||||
emitToken(SyntaxKind.VarKeyword, endPos);
|
||||
}
|
||||
write(" ");
|
||||
emit(node.declaration);
|
||||
}
|
||||
@@ -1298,7 +1305,17 @@ module ts {
|
||||
|
||||
function emitVariableStatement(node: VariableStatement) {
|
||||
emitLeadingComments(node);
|
||||
if (!(node.flags & NodeFlags.Export)) write("var ");
|
||||
if (!(node.flags & NodeFlags.Export)) {
|
||||
if (node.flags & NodeFlags.Let) {
|
||||
write("let ");
|
||||
}
|
||||
else if (node.flags & NodeFlags.Const) {
|
||||
write("const ");
|
||||
}
|
||||
else {
|
||||
write("var ");
|
||||
}
|
||||
}
|
||||
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
|
||||
write(";");
|
||||
emitTrailingComments(node);
|
||||
@@ -2314,7 +2331,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 +2355,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();
|
||||
}
|
||||
@@ -2822,7 +2852,15 @@ module ts {
|
||||
if (hasDeclarationWithEmit) {
|
||||
emitJsDocComments(node);
|
||||
emitDeclarationFlags(node);
|
||||
write("var ");
|
||||
if (node.flags & NodeFlags.Let) {
|
||||
write("let ");
|
||||
}
|
||||
else if (node.flags & NodeFlags.Const) {
|
||||
write("const ");
|
||||
}
|
||||
else {
|
||||
write("var ");
|
||||
}
|
||||
emitCommaList(node.declarations, emitVariableDeclaration);
|
||||
write(";");
|
||||
writeLine();
|
||||
@@ -2861,7 +2899,7 @@ module ts {
|
||||
}
|
||||
return {
|
||||
diagnosticMessage: diagnosticMessage,
|
||||
errorNode: node.parameters[0],
|
||||
errorNode: <Node>node.parameters[0],
|
||||
typeName: node.name
|
||||
};
|
||||
}
|
||||
@@ -2882,7 +2920,7 @@ module ts {
|
||||
}
|
||||
return {
|
||||
diagnosticMessage: diagnosticMessage,
|
||||
errorNode: node.name,
|
||||
errorNode: <Node>node.name,
|
||||
typeName: undefined
|
||||
};
|
||||
}
|
||||
@@ -3233,11 +3271,14 @@ module ts {
|
||||
}
|
||||
|
||||
var hasSemanticErrors = resolver.hasSemanticErrors();
|
||||
var hasEarlyErrors = resolver.hasEarlyErrors(targetSourceFile);
|
||||
|
||||
function emitFile(jsFilePath: string, sourceFile?: SourceFile) {
|
||||
emitJavaScript(jsFilePath, sourceFile);
|
||||
if (!hasSemanticErrors && compilerOptions.declaration) {
|
||||
emitDeclarations(jsFilePath, sourceFile);
|
||||
if (!hasEarlyErrors) {
|
||||
emitJavaScript(jsFilePath, sourceFile);
|
||||
if (!hasSemanticErrors && compilerOptions.declaration) {
|
||||
emitDeclarations(jsFilePath, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3277,7 +3318,9 @@ module ts {
|
||||
|
||||
// Check and update returnCode for syntactic and semantic
|
||||
var returnCode: EmitReturnStatus;
|
||||
if (hasEmitterError) {
|
||||
if (hasEarlyErrors) {
|
||||
returnCode = EmitReturnStatus.AllOutputGenerationSkipped;
|
||||
} else if (hasEmitterError) {
|
||||
returnCode = EmitReturnStatus.EmitErrorsEncountered;
|
||||
} else if (hasSemanticErrors && compilerOptions.declaration) {
|
||||
returnCode = EmitReturnStatus.DeclarationGenerationSkipped;
|
||||
|
||||
+228
-39
@@ -67,6 +67,77 @@ module ts {
|
||||
return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getTextOfNode(identifier);
|
||||
}
|
||||
|
||||
export function isExpression(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.ArrayLiteral:
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
case SyntaxKind.PropertyAccess:
|
||||
case SyntaxKind.IndexedAccess:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TypeAssertion:
|
||||
case SyntaxKind.ParenExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.PrefixOperator:
|
||||
case SyntaxKind.PostfixOperator:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
return true;
|
||||
case SyntaxKind.QualifiedName:
|
||||
while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent;
|
||||
return node.parent.kind === SyntaxKind.TypeQuery;
|
||||
case SyntaxKind.Identifier:
|
||||
if (node.parent.kind === SyntaxKind.TypeQuery) {
|
||||
return true;
|
||||
}
|
||||
// Fall through
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
var parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.Property:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return (<VariableDeclaration>parent).initializer === node;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
return (<ExpressionStatement>parent).expression === node;
|
||||
case SyntaxKind.ForStatement:
|
||||
return (<ForStatement>parent).initializer === node ||
|
||||
(<ForStatement>parent).condition === node ||
|
||||
(<ForStatement>parent).iterator === node;
|
||||
case SyntaxKind.ForInStatement:
|
||||
return (<ForInStatement>parent).variable === node ||
|
||||
(<ForInStatement>parent).expression === node;
|
||||
case SyntaxKind.TypeAssertion:
|
||||
return node === (<TypeAssertion>parent).operand;
|
||||
default:
|
||||
if (isExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
||||
node = getErrorSpanForNode(node);
|
||||
var file = getSourceFileOfNode(node);
|
||||
@@ -227,6 +298,8 @@ module ts {
|
||||
return children((<TupleTypeNode>node).elementTypes);
|
||||
case SyntaxKind.UnionType:
|
||||
return children((<UnionTypeNode>node).types);
|
||||
case SyntaxKind.ParenType:
|
||||
return child((<ParenTypeNode>node).type);
|
||||
case SyntaxKind.ArrayLiteral:
|
||||
return children((<ArrayLiteral>node).elements);
|
||||
case SyntaxKind.ObjectLiteral:
|
||||
@@ -1076,7 +1149,7 @@ module ts {
|
||||
return isParameter();
|
||||
case ParsingContext.TypeArguments:
|
||||
case ParsingContext.TupleElementTypes:
|
||||
return isType();
|
||||
return token === SyntaxKind.CommaToken || isType();
|
||||
}
|
||||
|
||||
Debug.fail("Non-exhaustive case in 'isListElement'.");
|
||||
@@ -1658,6 +1731,14 @@ module ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseParenType(): ParenTypeNode {
|
||||
var node = <ParenTypeNode>createNode(SyntaxKind.ParenType);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.type = parseType();
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseFunctionType(signatureKind: SyntaxKind): TypeLiteralNode {
|
||||
var node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
|
||||
var member = <SignatureDeclaration>createNode(signatureKind);
|
||||
@@ -1691,10 +1772,7 @@ module ts {
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
return parseTupleType();
|
||||
case SyntaxKind.OpenParenToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
return parseFunctionType(SyntaxKind.CallSignature);
|
||||
case SyntaxKind.NewKeyword:
|
||||
return parseFunctionType(SyntaxKind.ConstructSignature);
|
||||
return parseParenType();
|
||||
default:
|
||||
if (isIdentifier()) {
|
||||
return parseTypeReference();
|
||||
@@ -1718,18 +1796,18 @@ module ts {
|
||||
case SyntaxKind.NewKeyword:
|
||||
return true;
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider an ( as the start of a type if we have () or (id
|
||||
// We don't want to consider things like (1) as a function type.
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||
return lookAhead(() => {
|
||||
nextToken();
|
||||
return token === SyntaxKind.CloseParenToken || isParameter();
|
||||
return token === SyntaxKind.CloseParenToken || isParameter() || isType();
|
||||
});
|
||||
default:
|
||||
return isIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
function parseNonUnionType(): TypeNode {
|
||||
function parsePrimaryType(): TypeNode {
|
||||
var type = parseNonArrayType();
|
||||
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
@@ -1740,13 +1818,13 @@ module ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function parseType(): TypeNode {
|
||||
var type = parseNonUnionType();
|
||||
function parseUnionType(): TypeNode {
|
||||
var type = parsePrimaryType();
|
||||
if (token === SyntaxKind.BarToken) {
|
||||
var types = <NodeArray<TypeNode>>[type];
|
||||
types.pos = type.pos;
|
||||
while (parseOptional(SyntaxKind.BarToken)) {
|
||||
types.push(parseNonUnionType());
|
||||
types.push(parsePrimaryType());
|
||||
}
|
||||
types.end = getNodeEnd();
|
||||
var node = <UnionTypeNode>createNode(SyntaxKind.UnionType, type.pos);
|
||||
@@ -1756,6 +1834,48 @@ module ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function isFunctionType(): boolean {
|
||||
return token === SyntaxKind.LessThanToken || token === SyntaxKind.OpenParenToken && lookAhead(() => {
|
||||
nextToken();
|
||||
if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) {
|
||||
// ( )
|
||||
// ( ...
|
||||
return true;
|
||||
}
|
||||
if (isIdentifier() || isModifier(token)) {
|
||||
nextToken();
|
||||
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
|
||||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
|
||||
isIdentifier() || isModifier(token)) {
|
||||
// ( id :
|
||||
// ( id ,
|
||||
// ( id ?
|
||||
// ( id =
|
||||
// ( modifier id
|
||||
return true;
|
||||
}
|
||||
if (token === SyntaxKind.CloseParenToken) {
|
||||
nextToken();
|
||||
if (token === SyntaxKind.EqualsGreaterThanToken) {
|
||||
// ( id ) =>
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function parseType(): TypeNode {
|
||||
if (isFunctionType()) {
|
||||
return parseFunctionType(SyntaxKind.CallSignature);
|
||||
}
|
||||
if (token === SyntaxKind.NewKeyword) {
|
||||
return parseFunctionType(SyntaxKind.ConstructSignature);
|
||||
}
|
||||
return parseUnionType();
|
||||
}
|
||||
|
||||
function parseTypeAnnotation(): TypeNode {
|
||||
return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined;
|
||||
}
|
||||
@@ -2342,13 +2462,29 @@ module ts {
|
||||
function parseTypeArguments(): NodeArray<TypeNode> {
|
||||
var typeArgumentListStart = scanner.getTokenPos();
|
||||
var errorCountBeforeTypeParameterList = file.syntacticErrors.length;
|
||||
var result = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
// We pass parseSingleTypeArgument instead of parseType as the element parser
|
||||
// because parseSingleTypeArgument knows how to parse a missing type argument.
|
||||
// This is useful for signature help. parseType has the disadvantage that when
|
||||
// it sees a missing type, it changes the LookAheadMode to Error, and the result
|
||||
// is a broken binary expression, which breaks signature help.
|
||||
var result = parseBracketedList(ParsingContext.TypeArguments, parseSingleTypeArgument, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
if (!result.length && file.syntacticErrors.length === errorCountBeforeTypeParameterList) {
|
||||
grammarErrorAtPos(typeArgumentListStart, scanner.getStartPos() - typeArgumentListStart, Diagnostics.Type_argument_list_cannot_be_empty);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseSingleTypeArgument(): TypeNode {
|
||||
if (token === SyntaxKind.CommaToken) {
|
||||
var errorStart = scanner.getTokenPos();
|
||||
var errorLength = scanner.getTextPos() - errorStart;
|
||||
grammarErrorAtPos(errorStart, errorLength, Diagnostics.Type_expected);
|
||||
return createNode(SyntaxKind.Missing);
|
||||
}
|
||||
|
||||
return parseType();
|
||||
}
|
||||
|
||||
function parsePrimaryExpression(): Expression {
|
||||
switch (token) {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
@@ -2558,11 +2694,14 @@ module ts {
|
||||
}
|
||||
|
||||
// STATEMENTS
|
||||
function parseStatementAllowingLetDeclaration() {
|
||||
return parseStatement(/*allowLetAndConstDeclarations*/ true);
|
||||
}
|
||||
|
||||
function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block {
|
||||
var node = <Block>createNode(SyntaxKind.Block);
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken) || ignoreMissingOpenBrace) {
|
||||
node.statements = parseList(ParsingContext.BlockStatements,checkForStrictMode, parseStatement);
|
||||
node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatementAllowingLetDeclaration);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
@@ -2608,8 +2747,8 @@ module ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node.thenStatement = parseStatement();
|
||||
node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined;
|
||||
node.thenStatement = parseStatement(/*allowLetAndConstDeclarations*/ false);
|
||||
node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement(/*allowLetAndConstDeclarations*/ false) : undefined;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -2619,7 +2758,7 @@ module ts {
|
||||
|
||||
var saveInIterationStatement = inIterationStatement;
|
||||
inIterationStatement = ControlBlockContext.Nested;
|
||||
node.statement = parseStatement();
|
||||
node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false);
|
||||
inIterationStatement = saveInIterationStatement;
|
||||
|
||||
parseExpected(SyntaxKind.WhileKeyword);
|
||||
@@ -2644,7 +2783,7 @@ module ts {
|
||||
|
||||
var saveInIterationStatement = inIterationStatement;
|
||||
inIterationStatement = ControlBlockContext.Nested;
|
||||
node.statement = parseStatement();
|
||||
node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false);
|
||||
inIterationStatement = saveInIterationStatement;
|
||||
|
||||
return finishNode(node);
|
||||
@@ -2656,11 +2795,29 @@ module ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
if (token !== SyntaxKind.SemicolonToken) {
|
||||
if (parseOptional(SyntaxKind.VarKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(0, true);
|
||||
var declarations = parseVariableDeclarationList(0, /*noIn*/ true);
|
||||
if (!declarations.length) {
|
||||
error(Diagnostics.Variable_declaration_list_cannot_be_empty);
|
||||
}
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.LetKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(NodeFlags.Let, /*noIn*/ true);
|
||||
if (!declarations.length) {
|
||||
error(Diagnostics.Variable_declaration_list_cannot_be_empty);
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
|
||||
}
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.ConstKeyword)) {
|
||||
var declarations = parseVariableDeclarationList(NodeFlags.Const, /*noIn*/ true);
|
||||
if (!declarations.length) {
|
||||
error(Diagnostics.Variable_declaration_list_cannot_be_empty);
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var varOrInit = parseExpression(true);
|
||||
}
|
||||
@@ -2699,7 +2856,7 @@ module ts {
|
||||
|
||||
var saveInIterationStatement = inIterationStatement;
|
||||
inIterationStatement = ControlBlockContext.Nested;
|
||||
forOrForInStatement.statement = parseStatement();
|
||||
forOrForInStatement.statement = parseStatement(/*allowLetAndConstDeclarations*/ false);
|
||||
inIterationStatement = saveInIterationStatement;
|
||||
|
||||
return finishNode(forOrForInStatement);
|
||||
@@ -2810,7 +2967,7 @@ module ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node.statement = parseStatement();
|
||||
node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false);
|
||||
node = finishNode(node);
|
||||
if (isInStrictMode) {
|
||||
// Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such
|
||||
@@ -2825,7 +2982,7 @@ module ts {
|
||||
parseExpected(SyntaxKind.CaseKeyword);
|
||||
node.expression = parseExpression();
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -2833,7 +2990,7 @@ module ts {
|
||||
var node = <CaseOrDefaultClause>createNode(SyntaxKind.DefaultClause);
|
||||
parseExpected(SyntaxKind.DefaultKeyword);
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -2940,9 +3097,9 @@ module ts {
|
||||
return token === SyntaxKind.WhileKeyword || token === SyntaxKind.DoKeyword || token === SyntaxKind.ForKeyword;
|
||||
}
|
||||
|
||||
function parseStatementWithLabelSet(): Statement {
|
||||
function parseStatementWithLabelSet(allowLetAndConstDeclarations: boolean): Statement {
|
||||
labelledStatementInfo.pushCurrentLabelSet(isIterationStatementStart());
|
||||
var statement = parseStatement();
|
||||
var statement = parseStatement(allowLetAndConstDeclarations);
|
||||
labelledStatementInfo.pop();
|
||||
return statement;
|
||||
}
|
||||
@@ -2951,7 +3108,7 @@ module ts {
|
||||
return isIdentifier() && lookAhead(() => nextToken() === SyntaxKind.ColonToken);
|
||||
}
|
||||
|
||||
function parseLabelledStatement(): LabeledStatement {
|
||||
function parseLabeledStatement(allowLetAndConstDeclarations: boolean): LabeledStatement {
|
||||
var node = <LabeledStatement>createNode(SyntaxKind.LabeledStatement);
|
||||
node.label = parseIdentifier();
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
@@ -2963,7 +3120,7 @@ module ts {
|
||||
|
||||
// We only want to call parseStatementWithLabelSet when the label set is complete
|
||||
// Therefore, keep parsing labels until we know we're done.
|
||||
node.statement = isLabel() ? parseLabelledStatement() : parseStatementWithLabelSet();
|
||||
node.statement = isLabel() ? parseLabeledStatement(allowLetAndConstDeclarations) : parseStatementWithLabelSet(allowLetAndConstDeclarations);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -2986,6 +3143,8 @@ module ts {
|
||||
return !inErrorRecovery;
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.IfKeyword:
|
||||
case SyntaxKind.DoKeyword:
|
||||
@@ -3027,12 +3186,14 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseStatement(): Statement {
|
||||
function parseStatement(allowLetAndConstDeclarations: boolean): Statement {
|
||||
switch (token) {
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false);
|
||||
case SyntaxKind.VarKeyword:
|
||||
return parseVariableStatement();
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
return parseVariableStatement(allowLetAndConstDeclarations);
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return parseFunctionDeclaration();
|
||||
case SyntaxKind.SemicolonToken:
|
||||
@@ -3066,16 +3227,12 @@ module ts {
|
||||
return parseDebuggerStatement();
|
||||
default:
|
||||
if (isLabel()) {
|
||||
return parseLabelledStatement();
|
||||
return parseLabeledStatement(allowLetAndConstDeclarations);
|
||||
}
|
||||
return parseExpressionStatement();
|
||||
}
|
||||
}
|
||||
|
||||
function parseStatementOrFunction(): Statement {
|
||||
return token === SyntaxKind.FunctionKeyword ? parseFunctionDeclaration() : parseStatement();
|
||||
}
|
||||
|
||||
function parseAndCheckFunctionBody(isConstructor: boolean): Block {
|
||||
var initialPosition = scanner.getTokenPos();
|
||||
var errorCountBeforeBody = file.syntacticErrors.length;
|
||||
@@ -3111,6 +3268,9 @@ module ts {
|
||||
if (inAmbientContext && node.initializer && errorCountBeforeVariableDeclaration === file.syntacticErrors.length) {
|
||||
grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
|
||||
}
|
||||
if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) {
|
||||
grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized);
|
||||
}
|
||||
if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) {
|
||||
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
|
||||
// and its Identifier is eval or arguments
|
||||
@@ -3124,17 +3284,42 @@ module ts {
|
||||
() => parseVariableDeclaration(flags, noIn), /*allowTrailingComma*/ false);
|
||||
}
|
||||
|
||||
function parseVariableStatement(pos?: number, flags?: NodeFlags): VariableStatement {
|
||||
function parseVariableStatement(allowLetAndConstDeclarations: boolean, pos?: number, flags?: NodeFlags): VariableStatement {
|
||||
var node = <VariableStatement>createNode(SyntaxKind.VariableStatement, pos);
|
||||
if (flags) node.flags = flags;
|
||||
var errorCountBeforeVarStatement = file.syntacticErrors.length;
|
||||
parseExpected(SyntaxKind.VarKeyword);
|
||||
node.declarations = parseVariableDeclarationList(flags, /*noIn*/false);
|
||||
if (token === SyntaxKind.LetKeyword) {
|
||||
node.flags |= NodeFlags.Let;
|
||||
}
|
||||
else if (token === SyntaxKind.ConstKeyword) {
|
||||
node.flags |= NodeFlags.Const;
|
||||
}
|
||||
else if (token !== SyntaxKind.VarKeyword) {
|
||||
error(Diagnostics.var_let_or_const_expected);
|
||||
}
|
||||
nextToken();
|
||||
node.declarations = parseVariableDeclarationList(node.flags, /*noIn*/false);
|
||||
parseSemicolon();
|
||||
finishNode(node);
|
||||
if (!node.declarations.length && file.syntacticErrors.length === errorCountBeforeVarStatement) {
|
||||
grammarErrorOnNode(node, Diagnostics.Variable_declaration_list_cannot_be_empty);
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
if (node.flags & NodeFlags.Let) {
|
||||
grammarErrorOnNode(node, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
|
||||
}
|
||||
else if (node.flags & NodeFlags.Const) {
|
||||
grammarErrorOnNode(node, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
|
||||
}
|
||||
}
|
||||
else if (!allowLetAndConstDeclarations) {
|
||||
if (node.flags & NodeFlags.Let) {
|
||||
grammarErrorOnNode(node, Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
|
||||
}
|
||||
else if (node.flags & NodeFlags.Const) {
|
||||
grammarErrorOnNode(node, Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -3713,6 +3898,8 @@ module ts {
|
||||
function isDeclaration(): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return true;
|
||||
case SyntaxKind.ClassKeyword:
|
||||
@@ -3763,7 +3950,9 @@ module ts {
|
||||
var result: Declaration;
|
||||
switch (token) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
result = parseVariableStatement(pos, flags);
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
result = parseVariableStatement(/*allowLetAndConstDeclarations*/ true, pos, flags);
|
||||
break;
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
result = parseFunctionDeclaration(pos, flags);
|
||||
@@ -3811,7 +4000,7 @@ module ts {
|
||||
var statementStart = scanner.getTokenPos();
|
||||
var statementFirstTokenLength = scanner.getTextPos() - statementStart;
|
||||
var errorCountBeforeStatement = file.syntacticErrors.length;
|
||||
var statement = parseStatement();
|
||||
var statement = parseStatement(/*allowLetAndConstDeclarations*/ true);
|
||||
|
||||
if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) {
|
||||
grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
/// <reference path="diagnosticInformationMap.generated.ts"/>
|
||||
|
||||
interface System {
|
||||
args: string[];
|
||||
@@ -68,7 +67,7 @@ var sys: System = (function () {
|
||||
return fileStream.ReadText();
|
||||
}
|
||||
catch (e) {
|
||||
throw e.number === -2147024809 ? new Error(ts.Diagnostics.Unsupported_file_encoding.key) : e;
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
fileStream.Close();
|
||||
|
||||
+19
-9
@@ -142,14 +142,19 @@ module ts {
|
||||
// otherwise use toLowerCase as a canonical form.
|
||||
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
// returned by CScript sys environment
|
||||
var unsupportedFileEncodingErrorCode = -2147024809;
|
||||
|
||||
function getSourceFile(filename: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
try {
|
||||
var text = sys.readFile(filename, options.charset);
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
onError(e.number === unsupportedFileEncodingErrorCode ?
|
||||
getDiagnosticText(Diagnostics.Unsupported_file_encoding) :
|
||||
e.message);
|
||||
}
|
||||
text = "";
|
||||
}
|
||||
@@ -356,13 +361,18 @@ module ts {
|
||||
else {
|
||||
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
|
||||
var checkStart = new Date().getTime();
|
||||
var semanticErrors = checker.getDiagnostics();
|
||||
var emitStart = new Date().getTime();
|
||||
var emitOutput = checker.emitFiles();
|
||||
var emitErrors = emitOutput.errors;
|
||||
exitStatus = emitOutput.emitResultStatus;
|
||||
var reportStart = new Date().getTime();
|
||||
errors = concatenate(semanticErrors, emitErrors);
|
||||
errors = checker.getDiagnostics();
|
||||
if (!checker.hasEarlyErrors()) {
|
||||
var emitStart = new Date().getTime();
|
||||
var emitOutput = checker.emitFiles();
|
||||
var emitErrors = emitOutput.errors;
|
||||
exitStatus = emitOutput.emitResultStatus;
|
||||
var reportStart = new Date().getTime();
|
||||
errors = concatenate(errors, emitErrors);
|
||||
}
|
||||
else {
|
||||
exitStatus = EmitReturnStatus.AllOutputGenerationSkipped;
|
||||
}
|
||||
}
|
||||
|
||||
reportDiagnostics(errors);
|
||||
|
||||
+90
-81
@@ -155,6 +155,7 @@ module ts {
|
||||
ArrayType,
|
||||
TupleType,
|
||||
UnionType,
|
||||
ParenType,
|
||||
// Expression
|
||||
ArrayLiteral,
|
||||
ObjectLiteral,
|
||||
@@ -225,7 +226,7 @@ module ts {
|
||||
FirstFutureReservedWord = ImplementsKeyword,
|
||||
LastFutureReservedWord = YieldKeyword,
|
||||
FirstTypeNode = TypeReference,
|
||||
LastTypeNode = UnionType,
|
||||
LastTypeNode = ParenType,
|
||||
FirstPunctuation = OpenBraceToken,
|
||||
LastPunctuation = CaretEqualsToken,
|
||||
FirstToken = EndOfFileToken,
|
||||
@@ -250,9 +251,12 @@ module ts {
|
||||
MultiLine = 0x00000100, // Multi-line array or object literal
|
||||
Synthetic = 0x00000200, // Synthetic node (for full fidelity)
|
||||
DeclarationFile = 0x00000400, // Node is a .d.ts file
|
||||
Let = 0x00000800, // Variable declaration
|
||||
Const = 0x00001000, // Variable declaration
|
||||
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static,
|
||||
AccessibilityModifier = Public | Private | Protected
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
BlockScoped = Let | Const
|
||||
}
|
||||
|
||||
export interface Node extends TextRange {
|
||||
@@ -346,6 +350,10 @@ module ts {
|
||||
types: NodeArray<TypeNode>;
|
||||
}
|
||||
|
||||
export interface ParenTypeNode extends TypeNode {
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface StringLiteralTypeNode extends TypeNode {
|
||||
text: string;
|
||||
}
|
||||
@@ -644,30 +652,26 @@ module ts {
|
||||
getParentOfSymbol(symbol: Symbol): Symbol;
|
||||
getTypeOfSymbol(symbol: Symbol): Type;
|
||||
getPropertiesOfType(type: Type): Symbol[];
|
||||
getPropertyOfType(type: Type, propetyName: string): Symbol;
|
||||
getPropertyOfType(type: Type, propertyName: string): Symbol;
|
||||
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
|
||||
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
|
||||
getReturnTypeOfSignature(signature: Signature): Type;
|
||||
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
|
||||
getSymbolInfo(node: Node): Symbol;
|
||||
getTypeOfNode(node: Node): Type;
|
||||
getApparentType(type: Type): ApparentType;
|
||||
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
|
||||
writeType(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
|
||||
writeSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
|
||||
getSymbolDisplayBuilder(): SymbolDisplayBuilder;
|
||||
getFullyQualifiedName(symbol: Symbol): string;
|
||||
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Node): Type;
|
||||
getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
|
||||
writeSignature(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
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;
|
||||
hasEarlyErrors(sourceFile?: SourceFile): boolean;
|
||||
|
||||
// Returns the constant value of this enum member, or 'undefined' if the enum member has a
|
||||
// computed value.
|
||||
@@ -677,8 +681,25 @@ module ts {
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
}
|
||||
|
||||
export interface SymbolDisplayBuilder {
|
||||
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
|
||||
buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
|
||||
buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -699,6 +720,7 @@ module ts {
|
||||
WriteArrowStyleSignature = 0x00000008, // Write arrow style signature
|
||||
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
|
||||
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
|
||||
InElementType = 0x00000040, // Writing an array or union element type
|
||||
}
|
||||
|
||||
export enum SymbolFormatFlags {
|
||||
@@ -745,52 +767,62 @@ module ts {
|
||||
// Returns the constant value this property access resolves to, or 'undefined' if it does
|
||||
// resolve to a constant.
|
||||
getConstantValue(node: PropertyAccess): number;
|
||||
hasEarlyErrors(sourceFile?: SourceFile): boolean;
|
||||
}
|
||||
|
||||
export enum SymbolFlags {
|
||||
Variable = 0x00000001, // Variable or parameter
|
||||
Property = 0x00000002, // Property or enum member
|
||||
EnumMember = 0x00000004, // Enum member
|
||||
Function = 0x00000008, // Function
|
||||
Class = 0x00000010, // Class
|
||||
Interface = 0x00000020, // Interface
|
||||
Enum = 0x00000040, // Enum
|
||||
ValueModule = 0x00000080, // Instantiated module
|
||||
NamespaceModule = 0x00000100, // Uninstantiated module
|
||||
TypeLiteral = 0x00000200, // Type Literal
|
||||
ObjectLiteral = 0x00000400, // Object Literal
|
||||
Method = 0x00000800, // Method
|
||||
Constructor = 0x00001000, // Constructor
|
||||
GetAccessor = 0x00002000, // Get accessor
|
||||
SetAccessor = 0x00004000, // Set accessor
|
||||
CallSignature = 0x00008000, // Call signature
|
||||
ConstructSignature = 0x00010000, // Construct signature
|
||||
IndexSignature = 0x00020000, // Index signature
|
||||
TypeParameter = 0x00040000, // Type parameter
|
||||
UnionProperty = 0x00080000, // Property in union type
|
||||
FunctionScopedVariable = 0x00000001, // Variable (var) or parameter
|
||||
Property = 0x00000002, // Property or enum member
|
||||
EnumMember = 0x00000004, // Enum member
|
||||
Function = 0x00000008, // Function
|
||||
Class = 0x00000010, // Class
|
||||
Interface = 0x00000020, // Interface
|
||||
Enum = 0x00000040, // Enum
|
||||
ValueModule = 0x00000080, // Instantiated module
|
||||
NamespaceModule = 0x00000100, // Uninstantiated module
|
||||
TypeLiteral = 0x00000200, // Type Literal
|
||||
ObjectLiteral = 0x00000400, // Object Literal
|
||||
Method = 0x00000800, // Method
|
||||
Constructor = 0x00001000, // Constructor
|
||||
GetAccessor = 0x00002000, // Get accessor
|
||||
SetAccessor = 0x00004000, // Set accessor
|
||||
CallSignature = 0x00008000, // Call signature
|
||||
ConstructSignature = 0x00010000, // Construct signature
|
||||
IndexSignature = 0x00020000, // Index signature
|
||||
TypeParameter = 0x00040000, // Type parameter
|
||||
|
||||
// Export markers (see comment in declareModuleMember in binder)
|
||||
ExportValue = 0x00100000, // Exported value marker
|
||||
ExportType = 0x00200000, // Exported type marker
|
||||
ExportNamespace = 0x00400000, // Exported namespace marker
|
||||
ExportValue = 0x00080000, // Exported value marker
|
||||
ExportType = 0x00100000, // Exported type marker
|
||||
ExportNamespace = 0x00200000, // Exported namespace marker
|
||||
|
||||
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
|
||||
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, // Prototype property (no source representation)
|
||||
UnionProperty = 0x08000000, // Property in union type
|
||||
|
||||
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty,
|
||||
|
||||
BlockScopedVariable = 0x10000000, // A block-scoped variable (let ot const)
|
||||
|
||||
Variable = FunctionScopedVariable | BlockScopedVariable,
|
||||
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
|
||||
Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter,
|
||||
Namespace = ValueModule | NamespaceModule,
|
||||
Module = ValueModule | NamespaceModule,
|
||||
Accessor = GetAccessor | SetAccessor,
|
||||
Signature = CallSignature | ConstructSignature | IndexSignature,
|
||||
|
||||
|
||||
// Variables can be redeclared, but can not redeclare a block-scoped declaration with the
|
||||
// same name, or any other value that is not a variable, e.g. ValueModule or Class
|
||||
FunctionScopedVariableExcludes = Value & ~FunctionScopedVariable,
|
||||
|
||||
// Block-scoped declarations are not allowed to be re-declared
|
||||
// they can not merge with anything in the value space
|
||||
BlockScopedVariableExcludes = Value,
|
||||
|
||||
ParameterExcludes = Value,
|
||||
VariableExcludes = Value & ~Variable,
|
||||
PropertyExcludes = Value,
|
||||
EnumMemberExcludes = Value,
|
||||
FunctionExcludes = Value & ~(Function | ValueModule),
|
||||
@@ -804,8 +836,9 @@ module ts {
|
||||
SetAccessorExcludes = Value & ~GetAccessor,
|
||||
TypeParameterExcludes = Type & ~TypeParameter,
|
||||
|
||||
|
||||
// Imports collide with all other imports with the same name.
|
||||
ImportExcludes = Import,
|
||||
ImportExcludes = Import,
|
||||
|
||||
ModuleMember = Variable | Function | Class | Interface | Enum | Module | Import,
|
||||
|
||||
@@ -896,7 +929,8 @@ module ts {
|
||||
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
|
||||
StringLike = String | StringLiteral,
|
||||
NumberLike = Number | Enum,
|
||||
ObjectType = Class | Interface | Reference | Tuple | Union | Anonymous,
|
||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||
Structured = Any | ObjectType | Union | TypeParameter
|
||||
}
|
||||
|
||||
// Properties common to all types
|
||||
@@ -919,12 +953,6 @@ module ts {
|
||||
// Object types (TypeFlags.ObjectType)
|
||||
export interface ObjectType extends Type { }
|
||||
|
||||
export interface ApparentType extends Type {
|
||||
// This property is not used. It is just to make the type system think ApparentType
|
||||
// is a strict subtype of Type.
|
||||
_apparentTypeBrand: any;
|
||||
}
|
||||
|
||||
// Class and interface types (TypeFlags.Class and TypeFlags.Interface)
|
||||
export interface InterfaceType extends ObjectType {
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
@@ -954,12 +982,13 @@ module ts {
|
||||
baseArrayType: TypeReference; // Array<T> where T is best common type of element types
|
||||
}
|
||||
|
||||
export interface UnionType extends ObjectType {
|
||||
types: Type[]; // Constituent types
|
||||
export interface UnionType extends Type {
|
||||
types: Type[]; // Constituent types
|
||||
resolvedProperties: SymbolTable; // Cache of resolved properties
|
||||
}
|
||||
|
||||
// Resolved object type
|
||||
export interface ResolvedObjectType extends ObjectType {
|
||||
// Resolved object or union type
|
||||
export interface ResolvedType extends ObjectType, UnionType {
|
||||
members: SymbolTable; // Properties by name
|
||||
properties: Symbol[]; // Properties
|
||||
callSignatures: Signature[]; // Call signatures of type
|
||||
@@ -1006,6 +1035,7 @@ module ts {
|
||||
|
||||
export interface InferenceContext {
|
||||
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
|
||||
inferUnionTypes: boolean; // Infer union types for disjoint candidates (otherwise undefinedType)
|
||||
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
|
||||
@@ -1015,6 +1045,7 @@ module ts {
|
||||
key: string;
|
||||
category: DiagnosticCategory;
|
||||
code: number;
|
||||
isEarly?: boolean;
|
||||
}
|
||||
|
||||
// A linked list of formatted diagnostic messages to be used as part of a multiline message.
|
||||
@@ -1035,6 +1066,7 @@ module ts {
|
||||
messageText: string;
|
||||
category: DiagnosticCategory;
|
||||
code: number;
|
||||
isEarly?: boolean;
|
||||
}
|
||||
|
||||
export enum DiagnosticCategory {
|
||||
@@ -1087,6 +1119,8 @@ module ts {
|
||||
export enum ScriptTarget {
|
||||
ES3,
|
||||
ES5,
|
||||
ES6,
|
||||
Latest = ES6,
|
||||
}
|
||||
|
||||
export interface ParsedCommandLine {
|
||||
@@ -1237,32 +1271,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;
|
||||
}
|
||||
|
||||
@@ -61,9 +61,11 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
var otherFiles: { unitName: string; content: string }[];
|
||||
var harnessCompiler: Harness.Compiler.HarnessCompiler;
|
||||
|
||||
var declToBeCompiled: { unitName: string; content: string }[] = [];
|
||||
var declOtherFiles: { unitName: string; content: string }[] = [];
|
||||
var declResult: Harness.Compiler.CompilerResult;
|
||||
var declFileCompilationResult: {
|
||||
declInputFiles: { unitName: string; content: string }[];
|
||||
declOtherFiles: { unitName: string; content: string }[];
|
||||
declResult: Harness.Compiler.CompilerResult;
|
||||
};
|
||||
|
||||
var createNewInstance = false;
|
||||
|
||||
@@ -147,9 +149,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
toBeCompiled = undefined;
|
||||
otherFiles = undefined;
|
||||
harnessCompiler = undefined;
|
||||
declToBeCompiled = undefined;
|
||||
declOtherFiles = undefined;
|
||||
declResult = undefined;
|
||||
declFileCompilationResult = undefined;
|
||||
});
|
||||
|
||||
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
|
||||
@@ -173,61 +173,18 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
// Source maps?
|
||||
it('Correct sourcemap content for ' + fileName, () => {
|
||||
if (result.sourceMapRecord) {
|
||||
if (options.sourceMap) {
|
||||
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => {
|
||||
return result.sourceMapRecord;
|
||||
return result.getSourceMapRecord();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Compile .d.ts files
|
||||
it('Correct compiler generated.d.ts for ' + fileName, () => {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
|
||||
}
|
||||
|
||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
|
||||
if (Harness.Compiler.isDTS(file.unitName)) {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
else {
|
||||
var declFile = findResultCodeFile(file.unitName);
|
||||
// Look if there is --out file corresponding to this ts file
|
||||
if (!declFile && options.out) {
|
||||
declFile = findResultCodeFile(options.out);
|
||||
if (!declFile || findUnit(declFile.fileName, declToBeCompiled) ||
|
||||
findUnit(declFile.fileName, declOtherFiles)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (declFile) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
return ts.forEach(result.declFilesCode,
|
||||
declFile => declFile.fileName === (fileName.substr(0, fileName.length - ".ts".length) + ".d.ts")
|
||||
? declFile : undefined);
|
||||
}
|
||||
|
||||
function findUnit(fileName: string, units: { unitName: string; content: string }[]) {
|
||||
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEach(toBeCompiled, file => addDtsFile(file, declToBeCompiled));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
harnessCompiler.compileFiles(declToBeCompiled, declOtherFiles, function (compileResult) {
|
||||
declResult = compileResult;
|
||||
}, function (settings) {
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
});
|
||||
}
|
||||
declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) {
|
||||
harnessCompiler.setCompilerSettings(tcSettings);
|
||||
}, options);
|
||||
});
|
||||
|
||||
|
||||
@@ -267,10 +224,10 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (declResult && declResult.errors.length) {
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n';
|
||||
jsCode += '\r\n\r\n';
|
||||
jsCode += getErrorBaseline(declToBeCompiled, declOtherFiles, declResult);
|
||||
jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
|
||||
+121
-40
@@ -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) {
|
||||
@@ -985,15 +985,85 @@ module FourSlash {
|
||||
return item.parameters[currentParam];
|
||||
}
|
||||
|
||||
private alignmentForExtraInfo = 50;
|
||||
|
||||
private spanInfoToString(pos: number, spanInfo: TypeScript.TextSpan, prefixString: string) {
|
||||
var resultString = "SpanInfo: " + JSON.stringify(spanInfo);
|
||||
if (spanInfo) {
|
||||
var spanString = this.activeFile.content.substr(spanInfo.start(), spanInfo.length());
|
||||
var spanLineMap = ts.computeLineStarts(spanString);
|
||||
for (var i = 0; i < spanLineMap.length; i++) {
|
||||
if (!i) {
|
||||
resultString += "\n";
|
||||
}
|
||||
resultString += prefixString + spanString.substring(spanLineMap[i], spanLineMap[i + 1]);
|
||||
}
|
||||
resultString += "\n" + prefixString + ":=> (" + this.getLineColStringAtPosition(spanInfo.start()) + ") to (" + this.getLineColStringAtPosition(spanInfo.end()) + ")";
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => TypeScript.TextSpan): string {
|
||||
var fileLineMap = ts.computeLineStarts(this.activeFile.content);
|
||||
var nextLine = 0;
|
||||
var resultString = "";
|
||||
var currentLine: string;
|
||||
var previousSpanInfo: string;
|
||||
var startColumn: number;
|
||||
var length: number;
|
||||
var prefixString = " >";
|
||||
|
||||
var addSpanInfoString = () => {
|
||||
if (previousSpanInfo) {
|
||||
resultString += currentLine;
|
||||
var thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~");
|
||||
thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " ");
|
||||
resultString += thisLineMarker;
|
||||
resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") ";
|
||||
resultString += " " + previousSpanInfo;
|
||||
previousSpanInfo = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
for (var pos = 0; pos < this.activeFile.content.length; pos++) {
|
||||
if (pos === 0 || pos === fileLineMap[nextLine]) {
|
||||
nextLine++;
|
||||
addSpanInfoString();
|
||||
if (resultString.length) {
|
||||
resultString += "\n--------------------------------";
|
||||
}
|
||||
currentLine = "\n" + nextLine.toString() + repeatString(3 - nextLine.toString().length, " ") + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n ";
|
||||
startColumn = 0;
|
||||
length = 0;
|
||||
}
|
||||
var spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString);
|
||||
if (previousSpanInfo && previousSpanInfo !== spanInfo) {
|
||||
addSpanInfoString();
|
||||
previousSpanInfo = spanInfo;
|
||||
startColumn = startColumn + length;
|
||||
length = 1;
|
||||
}
|
||||
else {
|
||||
previousSpanInfo = spanInfo;
|
||||
length++;
|
||||
}
|
||||
}
|
||||
addSpanInfoString();
|
||||
return resultString;
|
||||
|
||||
function repeatString(count: number, char: string) {
|
||||
var result = "";
|
||||
for (var i = 0; i < count; i++) {
|
||||
result += char;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public getBreakpointStatementLocation(pos: number) {
|
||||
this.taoInvalidReason = 'getBreakpointStatementLocation NYI';
|
||||
|
||||
var spanInfo = this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos);
|
||||
var resultString = "\n**Pos: " + pos + " SpanInfo: " + JSON.stringify(spanInfo) + "\n** Statement: ";
|
||||
if (spanInfo !== null) {
|
||||
resultString = resultString + this.activeFile.content.substr(spanInfo.start(), spanInfo.length());
|
||||
}
|
||||
return resultString;
|
||||
return this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos);
|
||||
}
|
||||
|
||||
public baselineCurrentFileBreakpointLocations() {
|
||||
@@ -1003,12 +1073,7 @@ module FourSlash {
|
||||
"Breakpoint Locations for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
() => {
|
||||
var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength();
|
||||
var resultString = "";
|
||||
for (var pos = 0; pos < fileLength; pos++) {
|
||||
resultString = resultString + this.getBreakpointStatementLocation(pos);
|
||||
}
|
||||
return resultString;
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
|
||||
},
|
||||
true /* run immediately */);
|
||||
}
|
||||
@@ -1056,7 +1121,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
Harness.IO.log(this.getBreakpointStatementLocation(pos));
|
||||
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(pos, this.getBreakpointStatementLocation(pos), " "));
|
||||
}
|
||||
|
||||
public printBreakpointAtCurrentLocation() {
|
||||
@@ -1502,7 +1567,7 @@ module FourSlash {
|
||||
throw new Error('verifyCaretAtMarker failed - expected to be in file "' + pos.fileName + '", but was in file "' + this.activeFile.fileName + '"');
|
||||
}
|
||||
if (pos.position !== this.currentCaretPosition) {
|
||||
throw new Error('verifyCaretAtMarker failed - expected to be at marker "/*' + markerName + '*/, but was at position ' + this.currentCaretPosition + '(' + this.getLineColStringAtCaret() + ')');
|
||||
throw new Error('verifyCaretAtMarker failed - expected to be at marker "/*' + markerName + '*/, but was at position ' + this.currentCaretPosition + '(' + this.getLineColStringAtPosition(this.currentCaretPosition) + ')');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1566,10 +1631,10 @@ module FourSlash {
|
||||
this.taoInvalidReason = 'verifyCurrentNameOrDottedNameSpanText NYI';
|
||||
|
||||
var span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition);
|
||||
if (span === null) {
|
||||
if (!span) {
|
||||
this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' +
|
||||
'\tExpected: "' + text + '"\n' +
|
||||
'\t Actual: null');
|
||||
'\t Actual: undefined');
|
||||
}
|
||||
|
||||
var actual = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(span.start(), span.end());
|
||||
@@ -1581,12 +1646,8 @@ module FourSlash {
|
||||
}
|
||||
|
||||
private getNameOrDottedNameSpan(pos: number) {
|
||||
var spanInfo = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos);
|
||||
var resultString = "\n**Pos: " + pos + " SpanInfo: " + JSON.stringify(spanInfo) + "\n** Statement: ";
|
||||
if (spanInfo !== null) {
|
||||
resultString = resultString + this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(spanInfo.start(), spanInfo.end());
|
||||
}
|
||||
return resultString;
|
||||
this.taoInvalidReason = 'getNameOrDottedNameSpan NYI';
|
||||
return this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos);
|
||||
}
|
||||
|
||||
public baselineCurrentFileNameOrDottedNameSpans() {
|
||||
@@ -1596,23 +1657,21 @@ module FourSlash {
|
||||
"Name OrDottedNameSpans for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
() => {
|
||||
var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength();
|
||||
var resultString = "";
|
||||
for (var pos = 0; pos < fileLength; pos++) {
|
||||
resultString = resultString + this.getNameOrDottedNameSpan(pos);
|
||||
}
|
||||
return resultString;
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos));
|
||||
},
|
||||
true /* run immediately */);
|
||||
}
|
||||
|
||||
public printNameOrDottedNameSpans(pos: number) {
|
||||
Harness.IO.log(this.getNameOrDottedNameSpan(pos));
|
||||
Harness.IO.log(this.spanInfoToString(pos, 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);
|
||||
this.raiseError('verifyClassifications failed - expected total classifications to be ' + expected.length +
|
||||
', but was ' + actual.length +
|
||||
jsonMismatchString());
|
||||
}
|
||||
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
@@ -1623,17 +1682,38 @@ module FourSlash {
|
||||
if (expectedType !== actualClassification.classificationType) {
|
||||
this.raiseError('verifyClassifications failed - expected classifications type to be ' +
|
||||
expectedType + ', but was ' +
|
||||
actualClassification.classificationType);
|
||||
actualClassification.classificationType +
|
||||
jsonMismatchString());
|
||||
}
|
||||
|
||||
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() + "}" +
|
||||
jsonMismatchString());
|
||||
}
|
||||
}
|
||||
|
||||
var actualText = this.activeFile.content.substr(actualSpan.start(), actualSpan.length());
|
||||
if (expectedClassification.text !== actualText) {
|
||||
this.raiseError('verifyClassifications failed - expected classificatied text to be ' +
|
||||
this.raiseError('verifyClassifications failed - expected classified text to be ' +
|
||||
expectedClassification.text + ', but was ' +
|
||||
actualText);
|
||||
actualText +
|
||||
jsonMismatchString());
|
||||
}
|
||||
}
|
||||
|
||||
function jsonMismatchString() {
|
||||
return sys.newLine +
|
||||
"expected: '" + sys.newLine + JSON.stringify(expected, (k,v) => v, 2) + "'" + sys.newLine +
|
||||
"actual: '" + sys.newLine + JSON.stringify(actual, (k, v) => v, 2) + "'";
|
||||
}
|
||||
}
|
||||
|
||||
public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) {
|
||||
@@ -1984,7 +2064,8 @@ module FourSlash {
|
||||
var newlinePos = text.indexOf('\n');
|
||||
if (newlinePos === -1) {
|
||||
return text;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (text.charAt(newlinePos - 1) === '\r') {
|
||||
newlinePos--;
|
||||
}
|
||||
@@ -2090,8 +2171,8 @@ module FourSlash {
|
||||
return this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition).line + 1;
|
||||
}
|
||||
|
||||
private getLineColStringAtCaret() {
|
||||
var pos = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition);
|
||||
private getLineColStringAtPosition(position: number) {
|
||||
var pos = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, position);
|
||||
return 'line ' + (pos.line + 1) + ', col ' + pos.character;
|
||||
}
|
||||
|
||||
@@ -2139,7 +2220,7 @@ module FourSlash {
|
||||
var host = Harness.Compiler.createCompilerHost([{ unitName: Harness.Compiler.fourslashFilename, content: undefined },
|
||||
{ unitName: fileName, content: content }],
|
||||
(fn, contents) => result = contents,
|
||||
ts.ScriptTarget.ES5,
|
||||
ts.ScriptTarget.Latest,
|
||||
sys.useCaseSensitiveFileNames);
|
||||
var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js" }, host);
|
||||
var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true);
|
||||
|
||||
+92
-15
@@ -139,6 +139,7 @@ module Harness {
|
||||
deleteFile(filename: string): void;
|
||||
listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[];
|
||||
log(text: string): void;
|
||||
getMemoryUsage? (): number;
|
||||
}
|
||||
|
||||
module IOImpl {
|
||||
@@ -275,6 +276,13 @@ module Harness {
|
||||
|
||||
return filesInFolder(path);
|
||||
}
|
||||
|
||||
export var getMemoryUsage: typeof IO.getMemoryUsage = () => {
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
}
|
||||
return process.memoryUsage().heapUsed;
|
||||
}
|
||||
}
|
||||
|
||||
export module Network {
|
||||
@@ -532,7 +540,7 @@ module Harness {
|
||||
}
|
||||
|
||||
export var defaultLibFileName = 'lib.d.ts';
|
||||
export var defaultLibSourceFile = ts.createSourceFile(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.ES5, /*version:*/ "0");
|
||||
export var defaultLibSourceFile = ts.createSourceFile(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*version:*/ "0");
|
||||
|
||||
// Cache these between executions so we don't have to re-parse them for every test
|
||||
export var fourslashFilename = 'fourslash.ts';
|
||||
@@ -685,6 +693,8 @@ module Harness {
|
||||
options.target = ts.ScriptTarget.ES3;
|
||||
} else if (setting.value.toLowerCase() === 'es5') {
|
||||
options.target = ts.ScriptTarget.ES5;
|
||||
} else if (setting.value.toLowerCase() === 'es6') {
|
||||
options.target = ts.ScriptTarget.ES6;
|
||||
} else {
|
||||
throw new Error('Unknown compile target ' + setting.value);
|
||||
}
|
||||
@@ -791,9 +801,11 @@ module Harness {
|
||||
var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true);
|
||||
checker.checkProgram();
|
||||
|
||||
var hasEarlyErrors = checker.hasEarlyErrors();
|
||||
|
||||
// only emit if there weren't parse errors
|
||||
var emitResult: ts.EmitResult;
|
||||
if (!hadParseErrors) {
|
||||
if (!hadParseErrors && !hasEarlyErrors) {
|
||||
emitResult = checker.emitFiles();
|
||||
}
|
||||
|
||||
@@ -804,15 +816,81 @@ module Harness {
|
||||
});
|
||||
this.lastErrors = errors;
|
||||
|
||||
var result = new CompilerResult(fileOutputs, errors, []);
|
||||
// Covert the source Map data into the baseline
|
||||
result.updateSourceMapRecord(program, emitResult ? emitResult.sourceMaps : undefined);
|
||||
var result = new CompilerResult(fileOutputs, errors, program, sys.getCurrentDirectory(), emitResult ? emitResult.sourceMaps : undefined);
|
||||
onComplete(result, checker);
|
||||
|
||||
// reset what newline means in case the last test changed it
|
||||
sys.newLine = '\r\n';
|
||||
return options;
|
||||
}
|
||||
|
||||
public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[],
|
||||
otherFiles: { unitName: string; content: string; }[],
|
||||
result: CompilerResult,
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions) {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
|
||||
}
|
||||
|
||||
// if the .d.ts is non-empty, confirm it compiles correctly as well
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
var declInputFiles: { unitName: string; content: string }[] = [];
|
||||
var declOtherFiles: { unitName: string; content: string }[] = [];
|
||||
var declResult: Harness.Compiler.CompilerResult;
|
||||
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) {
|
||||
declResult = compileResult;
|
||||
}, settingsCallback, options);
|
||||
|
||||
return { declInputFiles: declInputFiles, declOtherFiles: declOtherFiles, declResult: declResult };
|
||||
}
|
||||
|
||||
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
|
||||
if (isDTS(file.unitName)) {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
else if (isTS(file.unitName)) {
|
||||
var declFile = findResultCodeFile(file.unitName);
|
||||
if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
}
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
var dTsFileName = ts.forEach(result.program.getSourceFiles(), sourceFile => {
|
||||
if (sourceFile.filename === fileName) {
|
||||
// Is this file going to be emitted separately
|
||||
var sourceFileName: string;
|
||||
if (ts.isExternalModule(sourceFile) || !options.out) {
|
||||
if (options.outDir) {
|
||||
var sourceFilePath = ts.getNormalizedPathFromPathComponents(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram));
|
||||
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
|
||||
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
|
||||
}
|
||||
else {
|
||||
sourceFileName = sourceFile.filename;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Goes to single --out file
|
||||
sourceFileName = options.out;
|
||||
}
|
||||
|
||||
return ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
}
|
||||
});
|
||||
|
||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||
}
|
||||
|
||||
function findUnit(fileName: string, units: { unitName: string; content: string; }[]) {
|
||||
return ts.forEach(units, unit => unit.unitName === fileName ? unit : undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getMinimalDiagnostic(err: ts.Diagnostic): HarnessDiagnostic {
|
||||
@@ -948,10 +1026,6 @@ module Harness {
|
||||
}
|
||||
*/
|
||||
|
||||
/** Recreate the harness compiler instance to its default settings */
|
||||
export function recreate(options?: { useMinimalDefaultLib: boolean; noImplicitAny: boolean; }) {
|
||||
}
|
||||
|
||||
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
|
||||
var harnessCompiler: HarnessCompiler;
|
||||
|
||||
@@ -991,6 +1065,10 @@ module Harness {
|
||||
return str.substr(str.length - end.length) === end;
|
||||
}
|
||||
|
||||
export function isTS(fileName: string) {
|
||||
return stringEndsWith(fileName, '.ts');
|
||||
}
|
||||
|
||||
export function isDTS(fileName: string) {
|
||||
return stringEndsWith(fileName, '.d.ts');
|
||||
}
|
||||
@@ -1009,10 +1087,10 @@ module Harness {
|
||||
public errors: HarnessDiagnostic[] = [];
|
||||
public declFilesCode: GeneratedFile[] = [];
|
||||
public sourceMaps: GeneratedFile[] = [];
|
||||
public sourceMapRecord: string;
|
||||
|
||||
/** @param fileResults an array of strings for the fileName and an ITextWriter with its code */
|
||||
constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], sourceMapRecordLines: string[]) {
|
||||
constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], public program: ts.Program,
|
||||
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
|
||||
var lines: string[] = [];
|
||||
|
||||
fileResults.forEach(emittedFile => {
|
||||
@@ -1030,12 +1108,11 @@ module Harness {
|
||||
});
|
||||
|
||||
this.errors = errors;
|
||||
this.sourceMapRecord = sourceMapRecordLines.join('\r\n');
|
||||
}
|
||||
|
||||
public updateSourceMapRecord(program: ts.Program, sourceMapData: ts.SourceMapData[]) {
|
||||
if (sourceMapData) {
|
||||
this.sourceMapRecord = Harness.SourceMapRecoder.getSourceMapRecord(sourceMapData, program, this.files);
|
||||
public getSourceMapRecord() {
|
||||
if (this.sourceMapData) {
|
||||
return Harness.SourceMapRecoder.getSourceMapRecord(this.sourceMapData, this.program, this.files);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ module Harness.LanguageService {
|
||||
|
||||
/** Parse file given its source text */
|
||||
public parseSourceText(fileName: string, sourceText: TypeScript.IScriptSnapshot): TypeScript.SourceUnitSyntax {
|
||||
return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), ts.ScriptTarget.ES5, TypeScript.isDTSFile(fileName)).sourceUnit();
|
||||
return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), ts.ScriptTarget.Latest, TypeScript.isDTSFile(fileName)).sourceUnit();
|
||||
}
|
||||
|
||||
/** Parse a file on disk given its fileName */
|
||||
|
||||
@@ -419,6 +419,16 @@ class ProjectRunner extends RunnerBase {
|
||||
// })
|
||||
//});
|
||||
}
|
||||
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
nodeCompilerResult = undefined;
|
||||
amdCompilerResult = undefined;
|
||||
testCase = undefined;
|
||||
testFileText = undefined;
|
||||
testCaseJustName = undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
// ///<reference path='fourslashRunner.ts' />
|
||||
/// <reference path='projectsRunner.ts' />
|
||||
/// <reference path='rwcRunner.ts' />
|
||||
/// <reference path='unittestrunner.ts' />
|
||||
|
||||
function runTests(runners: RunnerBase[]) {
|
||||
if (reverse) {
|
||||
@@ -67,9 +66,6 @@ if (testConfigFile !== '') {
|
||||
case 'fourslash-generated':
|
||||
runners.push(new GeneratedFourslashRunner());
|
||||
break;
|
||||
case 'unittests':
|
||||
runners.push(new UnitTestRunner());
|
||||
break;
|
||||
case 'rwc':
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
@@ -93,9 +89,6 @@ if (runners.length === 0) {
|
||||
// language services
|
||||
runners.push(new FourslashRunner());
|
||||
//runners.push(new GeneratedFourslashRunner());
|
||||
|
||||
// unittests
|
||||
runners.push(new UnitTestRunner());
|
||||
}
|
||||
|
||||
sys.newLine = '\r\n';
|
||||
|
||||
+138
-111
@@ -46,144 +46,171 @@ module RWC {
|
||||
}
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler();
|
||||
var opts: ts.ParsedCommandLine;
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
var inputFiles: { unitName: string; content: string; }[] = [];
|
||||
var otherFiles: { unitName: string; content: string; }[] = [];
|
||||
var compilerResult: Harness.Compiler.CompilerResult;
|
||||
var compilerOptions: ts.CompilerOptions;
|
||||
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
|
||||
var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2];
|
||||
// Compile .d.ts files
|
||||
var declFileCompilationResult: {
|
||||
declInputFiles: { unitName: string; content: string }[];
|
||||
declOtherFiles: { unitName: string; content: string }[];
|
||||
declResult: Harness.Compiler.CompilerResult;
|
||||
};
|
||||
|
||||
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
var errors = '';
|
||||
|
||||
it('has parsable options', () => {
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments);
|
||||
assert.equal(opts.errors.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
var inputFiles: { unitName: string; content: string; }[] = [];
|
||||
var otherFiles: { unitName: string; content: string; }[] = [];
|
||||
var compilerResult: Harness.Compiler.CompilerResult;
|
||||
it('can compile', () => {
|
||||
runWithIOLog(ioLog, () => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
// Load the files
|
||||
ts.forEach(opts.filenames, fileName => {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
});
|
||||
|
||||
if (!opts.options.noLib) {
|
||||
// Find the lib.d.ts file in the input file and add it to the input files list
|
||||
var libFile = ts.forEach(ioLog.filesRead, fileRead=> Harness.isLibraryFile(fileRead.path) ? fileRead.path : undefined);
|
||||
if (libFile) {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(libFile));
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEach(ioLog.filesRead, fileRead => {
|
||||
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileRead.path));
|
||||
var inInputList = ts.forEach(inputFiles, inputFile=> inputFile.unitName === resolvedPath);
|
||||
if (!inInputList) {
|
||||
// Add the file to other files
|
||||
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
});
|
||||
|
||||
// do not use lib since we already read it in above
|
||||
opts.options.noLib = true;
|
||||
|
||||
// Emit the results
|
||||
harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
|
||||
compilerResult = compileResult;
|
||||
}, /*settingsCallback*/ undefined, opts.options);
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
inputFiles = undefined;
|
||||
otherFiles = undefined;
|
||||
compilerResult = undefined;
|
||||
compilerOptions = undefined;
|
||||
baselineOpts = undefined;
|
||||
baseName = undefined;
|
||||
declFileCompilationResult = undefined;
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileName));
|
||||
try {
|
||||
var content = sys.readFile(resolvedPath);
|
||||
it('can compile', () => {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler();
|
||||
var opts: ts.ParsedCommandLine;
|
||||
|
||||
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments);
|
||||
assert.equal(opts.errors.length, 0);
|
||||
});
|
||||
|
||||
runWithIOLog(ioLog, () => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
// Load the files
|
||||
ts.forEach(opts.filenames, fileName => {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
});
|
||||
|
||||
if (!opts.options.noLib) {
|
||||
// Find the lib.d.ts file in the input file and add it to the input files list
|
||||
var libFile = ts.forEach(ioLog.filesRead, fileRead=> Harness.isLibraryFile(fileRead.path) ? fileRead.path : undefined);
|
||||
if (libFile) {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(libFile));
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEach(ioLog.filesRead, fileRead => {
|
||||
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileRead.path));
|
||||
var inInputList = ts.forEach(inputFiles, inputFile=> inputFile.unitName === resolvedPath);
|
||||
if (!inInputList) {
|
||||
// Add the file to other files
|
||||
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
});
|
||||
|
||||
// do not use lib since we already read it in above
|
||||
opts.options.noLib = true;
|
||||
|
||||
// Emit the results
|
||||
compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
|
||||
compilerResult = compileResult;
|
||||
}, /*settingsCallback*/ undefined, opts.options);
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(fileName));
|
||||
try {
|
||||
var content = sys.readFile(resolvedPath);
|
||||
}
|
||||
catch (e) {
|
||||
// Leave content undefined.
|
||||
}
|
||||
return { unitName: resolvedPath, content: content };
|
||||
}
|
||||
catch (e) {
|
||||
// Leave content undefined.
|
||||
}
|
||||
return { unitName: resolvedPath, content: content };
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Baselines
|
||||
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
|
||||
var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2];
|
||||
// Baselines
|
||||
it('Correct compiler generated.d.ts', () => {
|
||||
declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions);
|
||||
});
|
||||
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
|
||||
return collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s));
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has the expected declaration file content', () => {
|
||||
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
|
||||
if (compilerResult.errors.length || !compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
return collateOutputs(compilerResult.declFilesCode);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has the expected source maps', () => {
|
||||
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
|
||||
if (!compilerResult.sourceMaps.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return collateOutputs(compilerResult.sourceMaps);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has correct source map record', () => {
|
||||
if (compilerResult.sourceMapRecord) {
|
||||
Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
|
||||
return compilerResult.sourceMapRecord;
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
|
||||
return collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s));
|
||||
}, false, baselineOpts);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
it('has the expected declaration file content', () => {
|
||||
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
|
||||
if (compilerResult.errors.length || !compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
return collateOutputs(compilerResult.declFilesCode);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has the expected source maps', () => {
|
||||
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
|
||||
if (!compilerResult.sourceMaps.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return collateOutputs(compilerResult.sourceMaps);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
//it('has correct source map record', () => {
|
||||
// if (compilerOptions.sourceMap) {
|
||||
// Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
|
||||
// return compilerResult.getSourceMapRecord();
|
||||
// }, false, baselineOpts);
|
||||
// }
|
||||
//});
|
||||
|
||||
it('has the expected errors', () => {
|
||||
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
it('has no errors in generated declaration files', () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline('has no errors in generated declaration files', baseName + '.dts.errors.txt', () => {
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
|
||||
sys.newLine + sys.newLine +
|
||||
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}, false, baselineOpts);
|
||||
}
|
||||
});
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles.concat(otherFiles), compilerResult.errors);
|
||||
}, false, baselineOpts);
|
||||
// TODO: Type baselines (need to refactor out from compilerRunner)
|
||||
});
|
||||
|
||||
// TODO: Type baselines (need to refactor out from compilerRunner)
|
||||
}
|
||||
}
|
||||
|
||||
class RWCRunner extends RunnerBase {
|
||||
private runnerPath = "tests/runners/rwc";
|
||||
private sourcePath = "tests/cases/rwc/";
|
||||
|
||||
private harnessCompiler: Harness.Compiler.HarnessCompiler;
|
||||
private static sourcePath = "tests/cases/rwc/";
|
||||
|
||||
/** Setup the runner's tests so that they are ready to be executed by the harness
|
||||
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Recreate the compiler with the default lib
|
||||
Harness.Compiler.recreate({ useMinimalDefaultLib: false, noImplicitAny: false });
|
||||
this.harnessCompiler = Harness.Compiler.getCompiler();
|
||||
|
||||
// Read in and evaluate the test list
|
||||
var testList = Harness.IO.listFiles(this.sourcePath, /.+\.json$/);
|
||||
var testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||
for (var i = 0; i < testList.length; i++) {
|
||||
this.runTest(testList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private runTest(jsonFilename: string) {
|
||||
describe("Testing a RWC project: " + jsonFilename, () => {
|
||||
RWC.runRWCTest(jsonFilename);
|
||||
});
|
||||
RWC.runRWCTest(jsonFilename);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
///<reference path="harness.ts" />
|
||||
///<reference path="runnerbase.ts" />
|
||||
|
||||
class UnitTestRunner extends RunnerBase {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public initializeTests() {
|
||||
this.tests = this.enumerateFiles('tests/cases/unittests/services', /\.ts/i);
|
||||
|
||||
var outfile = new Harness.Compiler.WriterAggregator()
|
||||
var outerr = new Harness.Compiler.WriterAggregator();
|
||||
// note this is running immediately to generate tests to be run later inside describe/it
|
||||
// need a fresh instance so that the previous runner's last test is not hanging around
|
||||
var harnessCompiler = Harness.Compiler.getCompiler({ useExistingInstance: false });
|
||||
|
||||
var toBeAdded = this.tests.map(test => {
|
||||
return { unitName: test, content: Harness.IO.readFile(test) }
|
||||
});
|
||||
harnessCompiler.addInputFiles(toBeAdded);
|
||||
harnessCompiler.setCompilerOptions({ noResolve: true });
|
||||
|
||||
var stdout = new Harness.Compiler.EmitterIOHost();
|
||||
var emitDiagnostics = harnessCompiler.emitAll(stdout);
|
||||
var results = stdout.toArray();
|
||||
var lines: string[] = [];
|
||||
results.forEach(v => lines = lines.concat(v.file.lines));
|
||||
var code = lines.join("\n")
|
||||
|
||||
var nodeContext: any = undefined;
|
||||
if (Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Node) {
|
||||
nodeContext = {
|
||||
require: require,
|
||||
process: process,
|
||||
describe: describe,
|
||||
it: it,
|
||||
assert: assert,
|
||||
beforeEach: beforeEach,
|
||||
afterEach: afterEach,
|
||||
before: before,
|
||||
after: after,
|
||||
Harness: Harness,
|
||||
IO: Harness.IO,
|
||||
ts: ts,
|
||||
TypeScript: TypeScript
|
||||
// FourSlash: FourSlash
|
||||
};
|
||||
}
|
||||
|
||||
describe("Setup compiler for compiler unittests", () => {
|
||||
// ensures a clean compiler instance when tests are eventually executed following this describe block
|
||||
harnessCompiler = Harness.Compiler.getCompiler({
|
||||
useExistingInstance: false,
|
||||
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
|
||||
});
|
||||
});
|
||||
|
||||
// this generated code is a series of top level describe/it blocks that will run in between the setup and cleanup blocks in this file
|
||||
Utils.evalFile(code, "generated_test_code.js", nodeContext);
|
||||
|
||||
describe("Cleanup after unittests", () => {
|
||||
var harnessCompiler = Harness.Compiler.getCompiler({
|
||||
useExistingInstance: false,
|
||||
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
|
||||
});
|
||||
});
|
||||
|
||||
// note this runs immediately (ie before this same code in the describe block above)
|
||||
// to make sure the next runner doesn't include the previous one's stuff
|
||||
harnessCompiler = Harness.Compiler.getCompiler({ useExistingInstance: false });
|
||||
}
|
||||
}
|
||||
+456
-1038
File diff suppressed because it is too large
Load Diff
@@ -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() + " {");
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ module TypeScript {
|
||||
|
||||
export function preProcessFile(fileName: string, sourceText: IScriptSnapshot, readImportFiles = true): IPreProcessedFileInfo {
|
||||
var text = SimpleText.fromScriptSnapshot(sourceText);
|
||||
var scanner = Scanner.createScanner(ts.ScriptTarget.ES5, text, reportDiagnostic);
|
||||
var scanner = Scanner.createScanner(ts.ScriptTarget.Latest, text, reportDiagnostic);
|
||||
|
||||
var firstToken = scanner.scan(/*allowRegularExpression:*/ false);
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,12 @@ module ts.NavigationBar {
|
||||
return createItem(node, getTextOfNode((<FunctionDeclaration>node).name), ts.ScriptElementKind.functionElement);
|
||||
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.variableElement);
|
||||
if (node.flags & NodeFlags.Const) {
|
||||
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.constantElement);
|
||||
}
|
||||
else {
|
||||
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.variableElement);
|
||||
}
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement);
|
||||
|
||||
+212
-150
@@ -78,7 +78,7 @@ module ts {
|
||||
update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile;
|
||||
}
|
||||
|
||||
var scanner: Scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true);
|
||||
var scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
|
||||
|
||||
var emptyArray: any[] = [];
|
||||
|
||||
@@ -576,7 +576,7 @@ module ts {
|
||||
return this.checker.getPropertyOfType(this, propertyName);
|
||||
}
|
||||
getApparentProperties(): Symbol[] {
|
||||
return this.checker.getAugmentedPropertiesOfApparentType(this);
|
||||
return this.checker.getAugmentedPropertiesOfType(this);
|
||||
}
|
||||
getCallSignatures(): Signature[] {
|
||||
return this.checker.getSignaturesOfType(this, SignatureKind.Call);
|
||||
@@ -1022,12 +1022,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;
|
||||
@@ -1238,7 +1263,9 @@ module ts {
|
||||
|
||||
static label = "label";
|
||||
|
||||
static alias = "alias"
|
||||
static alias = "alias";
|
||||
|
||||
static constantElement = "constant";
|
||||
}
|
||||
|
||||
export class ScriptElementKindModifier {
|
||||
@@ -1334,7 +1361,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++; },
|
||||
@@ -1458,7 +1490,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] {
|
||||
export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] {
|
||||
writeDisplayParts(displayPartWriter);
|
||||
var result = displayPartWriter.displayParts();
|
||||
displayPartWriter.clear();
|
||||
@@ -1467,26 +1499,26 @@ module ts {
|
||||
|
||||
export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] {
|
||||
return mapToDisplayParts(writer => {
|
||||
typechecker.writeType(type, writer, enclosingDeclaration, flags);
|
||||
typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
||||
});
|
||||
}
|
||||
|
||||
export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[] {
|
||||
return mapToDisplayParts(writer => {
|
||||
typeChecker.writeSymbol(symbol, writer, enclosingDeclaration, meaning, flags);
|
||||
typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags);
|
||||
});
|
||||
}
|
||||
|
||||
function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[]{
|
||||
return mapToDisplayParts(writer => {
|
||||
typechecker.writeSignature(signature, writer, enclosingDeclaration, flags);
|
||||
typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
|
||||
});
|
||||
}
|
||||
|
||||
export function getDefaultCompilerOptions(): CompilerOptions {
|
||||
// Set "ES5" target by default for language service
|
||||
// Set "ScriptTarget.Latest" target by default for language service
|
||||
return {
|
||||
target: ScriptTarget.ES5,
|
||||
target: ScriptTarget.Latest,
|
||||
module: ModuleKind.None,
|
||||
};
|
||||
}
|
||||
@@ -1948,18 +1980,32 @@ module ts {
|
||||
return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
|
||||
}
|
||||
|
||||
function isRightSideOfQualifiedName(node: Node) {
|
||||
return node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node;
|
||||
}
|
||||
|
||||
function isRightSideOfPropertyAccess(node: Node) {
|
||||
return node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node;
|
||||
}
|
||||
|
||||
function isCallExpressionTarget(node: Node): boolean {
|
||||
if (node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node)
|
||||
if (isRightSideOfPropertyAccess(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.parent.kind === SyntaxKind.CallExpression && (<CallExpression>node.parent).func === node;
|
||||
}
|
||||
|
||||
function isNewExpressionTarget(node: Node): boolean {
|
||||
if (node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node)
|
||||
if (isRightSideOfPropertyAccess(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.parent.kind === SyntaxKind.NewExpression && (<CallExpression>node.parent).func === node;
|
||||
}
|
||||
|
||||
function isNameOfModuleDeclaration(node: Node) {
|
||||
return node.parent.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node.parent).name === node;
|
||||
}
|
||||
|
||||
function isNameOfFunctionDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.Identifier &&
|
||||
isAnyFunction(node.parent) && (<FunctionDeclaration>node.parent).name === node;
|
||||
@@ -1992,7 +2038,7 @@ module ts {
|
||||
|
||||
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.StringLiteral &&
|
||||
((node.parent.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node.parent).name === node) ||
|
||||
(isNameOfModuleDeclaration(node) ||
|
||||
(node.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent).externalModuleName === node));
|
||||
}
|
||||
|
||||
@@ -2578,10 +2624,9 @@ module ts {
|
||||
}
|
||||
|
||||
var type = typeInfoResolver.getTypeOfNode(mappedNode);
|
||||
var apparentType = type && typeInfoResolver.getApparentType(type);
|
||||
if (apparentType) {
|
||||
if (type) {
|
||||
// Filter private properties
|
||||
forEach(apparentType.getApparentProperties(), symbol => {
|
||||
forEach(type.getApparentProperties(), symbol => {
|
||||
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccess>(mappedNode.parent), symbol.name)) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
@@ -2701,7 +2746,7 @@ module ts {
|
||||
|
||||
// TODO(drosen): use contextual SemanticMeaning.
|
||||
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker): string {
|
||||
var flags = typeInfoResolver.getRootSymbols(symbol)[0].getFlags();
|
||||
var flags = symbol.getFlags();
|
||||
|
||||
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
|
||||
if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement;
|
||||
@@ -2729,15 +2774,32 @@ module ts {
|
||||
if (isFirstDeclarationOfSymbolParameter(symbol)) {
|
||||
return ScriptElementKind.parameterElement;
|
||||
}
|
||||
else if(symbol.valueDeclaration && symbol.valueDeclaration.flags & NodeFlags.Const) {
|
||||
return ScriptElementKind.constantElement;
|
||||
}
|
||||
return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : 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;
|
||||
if (flags & SymbolFlags.Method) return ScriptElementKind.memberFunctionElement;
|
||||
if (flags & SymbolFlags.Property) return ScriptElementKind.memberVariableElement;
|
||||
if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
|
||||
|
||||
if (flags & SymbolFlags.Property) {
|
||||
if (flags & SymbolFlags.UnionProperty) {
|
||||
return forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => {
|
||||
var rootSymbolFlags = rootSymbol.getFlags();
|
||||
if (rootSymbolFlags & SymbolFlags.Property) {
|
||||
return ScriptElementKind.memberVariableElement;
|
||||
}
|
||||
if (rootSymbolFlags & SymbolFlags.GetAccessor) return ScriptElementKind.memberVariableElement;
|
||||
if (rootSymbolFlags & SymbolFlags.SetAccessor) return ScriptElementKind.memberVariableElement;
|
||||
Debug.assert(rootSymbolFlags & SymbolFlags.Method);
|
||||
}) || ScriptElementKind.memberFunctionElement;
|
||||
}
|
||||
return ScriptElementKind.memberVariableElement;
|
||||
}
|
||||
|
||||
return ScriptElementKind.unknown;
|
||||
}
|
||||
|
||||
@@ -2760,7 +2822,7 @@ module ts {
|
||||
case SyntaxKind.ClassDeclaration: return ScriptElementKind.classElement;
|
||||
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
|
||||
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
|
||||
case SyntaxKind.VariableDeclaration: return ScriptElementKind.variableElement;
|
||||
case SyntaxKind.VariableDeclaration: return node.flags & NodeFlags.Const ? ScriptElementKind.constantElement: ScriptElementKind.variableElement;
|
||||
case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement;
|
||||
case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement;
|
||||
case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement;
|
||||
@@ -2789,7 +2851,7 @@ module ts {
|
||||
semanticMeaning = getMeaningFromLocation(location)) {
|
||||
var displayParts: SymbolDisplayPart[] = [];
|
||||
var documentation: SymbolDisplayPart[];
|
||||
var symbolFlags = typeResolver.getRootSymbols(symbol)[0].flags;
|
||||
var symbolFlags = symbol.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
|
||||
@@ -2849,6 +2911,7 @@ module ts {
|
||||
switch (symbolKind) {
|
||||
case ScriptElementKind.memberVariableElement:
|
||||
case ScriptElementKind.variableElement:
|
||||
case ScriptElementKind.constantElement:
|
||||
case ScriptElementKind.parameterElement:
|
||||
case ScriptElementKind.localVariableElement:
|
||||
// If it is call or construct signature of lambda's write type name
|
||||
@@ -3004,7 +3067,7 @@ module ts {
|
||||
// If the type is type parameter, format it specially
|
||||
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) {
|
||||
var typeParameterParts = mapToDisplayParts(writer => {
|
||||
typeResolver.writeTypeParameter(<TypeParameter>type, writer, enclosingDeclaration);
|
||||
typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(<TypeParameter>type, writer, enclosingDeclaration);
|
||||
});
|
||||
displayParts.push.apply(displayParts, typeParameterParts);
|
||||
}
|
||||
@@ -3016,7 +3079,8 @@ module ts {
|
||||
symbolFlags & SymbolFlags.Method ||
|
||||
symbolFlags & SymbolFlags.Constructor ||
|
||||
symbolFlags & SymbolFlags.Signature ||
|
||||
symbolFlags & SymbolFlags.Accessor) {
|
||||
symbolFlags & SymbolFlags.Accessor ||
|
||||
symbolKind === ScriptElementKind.memberFunctionElement) {
|
||||
var allSignatures = type.getCallSignatures();
|
||||
addSignatureDisplayParts(allSignatures[0], allSignatures);
|
||||
}
|
||||
@@ -3072,7 +3136,7 @@ module ts {
|
||||
|
||||
function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) {
|
||||
var typeParameterParts = mapToDisplayParts(writer => {
|
||||
typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration);
|
||||
typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
|
||||
});
|
||||
displayParts.push.apply(displayParts, typeParameterParts);
|
||||
}
|
||||
@@ -3872,8 +3936,8 @@ module ts {
|
||||
// before and after it have to be a non-identifier char).
|
||||
var endPosition = position + symbolNameLength;
|
||||
|
||||
if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.ES5)) &&
|
||||
(endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.ES5))) {
|
||||
if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) &&
|
||||
(endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) {
|
||||
// Found a real match. Keep searching.
|
||||
positions.push(position);
|
||||
}
|
||||
@@ -4524,8 +4588,9 @@ module ts {
|
||||
}
|
||||
|
||||
function isTypeReference(node: Node): boolean {
|
||||
if (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node)
|
||||
if (isRightSideOfQualifiedName(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeReference;
|
||||
}
|
||||
@@ -4675,67 +4740,64 @@ module ts {
|
||||
}
|
||||
|
||||
function getNameOrDottedNameSpan(filename: string, startPos: number, endPos: number): TypeScript.TextSpan {
|
||||
function getTypeInfoEligiblePath(filename: string, position: number, isConstructorValidPosition: boolean) {
|
||||
var sourceUnit = syntaxTreeCache.getCurrentFileSyntaxTree(filename).sourceUnit();
|
||||
filename = ts.normalizeSlashes(filename);
|
||||
// Get node at the location
|
||||
var node = getTouchingPropertyName(getCurrentSourceFile(filename), startPos);
|
||||
|
||||
var ast = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, position, /*useTrailingTriviaAsLimChar*/ false, /*forceInclusive*/ true);
|
||||
if (ast === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ast.kind() === TypeScript.SyntaxKind.ParameterList && ast.parent.kind() === TypeScript.SyntaxKind.CallSignature && ast.parent.parent.kind() === TypeScript.SyntaxKind.ConstructorDeclaration) {
|
||||
ast = ast.parent.parent;
|
||||
}
|
||||
|
||||
switch (ast.kind()) {
|
||||
default:
|
||||
return null;
|
||||
case TypeScript.SyntaxKind.ConstructorDeclaration:
|
||||
var constructorAST = <TypeScript.ConstructorDeclarationSyntax>ast;
|
||||
if (!isConstructorValidPosition || !(position >= TypeScript.start(constructorAST) && position <= TypeScript.start(constructorAST) + "constructor".length)) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return ast;
|
||||
}
|
||||
case TypeScript.SyntaxKind.FunctionDeclaration:
|
||||
return null;
|
||||
case TypeScript.SyntaxKind.MemberAccessExpression:
|
||||
case TypeScript.SyntaxKind.QualifiedName:
|
||||
case TypeScript.SyntaxKind.SuperKeyword:
|
||||
case TypeScript.SyntaxKind.StringLiteral:
|
||||
case TypeScript.SyntaxKind.ThisKeyword:
|
||||
case TypeScript.SyntaxKind.IdentifierName:
|
||||
return ast;
|
||||
}
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccess:
|
||||
case SyntaxKind.QualifiedName:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.Identifier:
|
||||
break;
|
||||
|
||||
var node = getTypeInfoEligiblePath(filename, startPos, false);
|
||||
if (!node) return null;
|
||||
// Cant create the text span
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
while (node) {
|
||||
if (TypeScript.ASTHelpers.isNameOfMemberAccessExpression(node) ||
|
||||
TypeScript.ASTHelpers.isRightSideOfQualifiedName(node)) {
|
||||
node = node.parent;
|
||||
var nodeForStartPos = node;
|
||||
while (true) {
|
||||
if (isRightSideOfPropertyAccess(nodeForStartPos) || isRightSideOfQualifiedName(nodeForStartPos)) {
|
||||
// If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
|
||||
nodeForStartPos = nodeForStartPos.parent;
|
||||
}
|
||||
else if (isNameOfModuleDeclaration(nodeForStartPos)) {
|
||||
// If this is name of a module declarations, check if this is right side of dotted module name
|
||||
// If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
|
||||
// Then this name is name from dotted module
|
||||
if (nodeForStartPos.parent.parent.kind === SyntaxKind.ModuleDeclaration &&
|
||||
(<ModuleDeclaration>nodeForStartPos.parent.parent).body === nodeForStartPos.parent) {
|
||||
// Use parent module declarations name for start pos
|
||||
nodeForStartPos = (<ModuleDeclaration>nodeForStartPos.parent.parent).name;
|
||||
}
|
||||
else {
|
||||
// We have to use this name for start pos
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Is not a member expression so we have found the node for start pos
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TypeScript.TextSpan.fromBounds(
|
||||
TypeScript.start(node),
|
||||
TypeScript.end(node));
|
||||
return TypeScript.TextSpan.fromBounds(nodeForStartPos.getStart(), node.getEnd());
|
||||
}
|
||||
|
||||
function getBreakpointStatementAtPosition(filename: string, position: number) {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
filename = TypeScript.switchToForwardSlashes(filename);
|
||||
|
||||
var syntaxtree = getSyntaxTree(filename);
|
||||
return TypeScript.Services.Breakpoints.getBreakpointLocation(syntaxtree, position);
|
||||
filename = ts.normalizeSlashes(filename);
|
||||
return BreakpointResolver.spanInSourceFileAtLocation(getCurrentSourceFile(filename), position);
|
||||
}
|
||||
|
||||
function getNavigationBarItems(filename: string): NavigationBarItem[] {
|
||||
@@ -4773,7 +4835,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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4804,115 +4883,99 @@ module ts {
|
||||
var sourceFile = getCurrentSourceFile(fileName);
|
||||
|
||||
var result: ClassifiedSpan[] = [];
|
||||
processElement(sourceFile.getSourceUnit());
|
||||
processElement(sourceFile);
|
||||
|
||||
return result;
|
||||
|
||||
function classifyTrivia(trivia: TypeScript.ISyntaxTrivia) {
|
||||
if (trivia.isComment() && span.intersectsWith(trivia.fullStart(), trivia.fullWidth())) {
|
||||
function classifyComment(comment: CommentRange) {
|
||||
var width = comment.end - comment.pos;
|
||||
if (span.intersectsWith(comment.pos, width)) {
|
||||
result.push({
|
||||
textSpan: new TypeScript.TextSpan(trivia.fullStart(), trivia.fullWidth()),
|
||||
textSpan: new TypeScript.TextSpan(comment.pos, width),
|
||||
classificationType: ClassificationTypeNames.comment
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function classifyTriviaList(trivia: TypeScript.ISyntaxTriviaList) {
|
||||
for (var i = 0, n = trivia.count(); i < n; i++) {
|
||||
classifyTrivia(trivia.syntaxTriviaAt(i));
|
||||
}
|
||||
}
|
||||
function classifyToken(token: Node): void {
|
||||
forEach(getLeadingCommentRanges(sourceFile.text, token.getFullStart()), classifyComment);
|
||||
|
||||
function classifyToken(token: TypeScript.ISyntaxToken) {
|
||||
if (token.hasLeadingComment()) {
|
||||
classifyTriviaList(token.leadingTrivia());
|
||||
}
|
||||
|
||||
if (TypeScript.width(token) > 0) {
|
||||
if (token.getWidth() > 0) {
|
||||
var type = classifyTokenType(token);
|
||||
if (type) {
|
||||
result.push({
|
||||
textSpan: new TypeScript.TextSpan(TypeScript.start(token), TypeScript.width(token)),
|
||||
textSpan: new TypeScript.TextSpan(token.getStart(), token.getWidth()),
|
||||
classificationType: type
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (token.hasTrailingComment()) {
|
||||
classifyTriviaList(token.trailingTrivia());
|
||||
}
|
||||
forEach(getTrailingCommentRanges(sourceFile.text, token.getEnd()), classifyComment);
|
||||
}
|
||||
|
||||
function classifyTokenType(token: TypeScript.ISyntaxToken): string {
|
||||
var tokenKind = token.kind();
|
||||
if (TypeScript.SyntaxFacts.isAnyKeyword(token.kind())) {
|
||||
function classifyTokenType(token: Node): string {
|
||||
var tokenKind = token.kind;
|
||||
if (isKeyword(tokenKind)) {
|
||||
return ClassificationTypeNames.keyword;
|
||||
}
|
||||
|
||||
// Special case < and > If they appear in a generic context they are punctation,
|
||||
// Special case < and > If they appear in a generic context they are punctuation,
|
||||
// not operators.
|
||||
if (tokenKind === TypeScript.SyntaxKind.LessThanToken || tokenKind === TypeScript.SyntaxKind.GreaterThanToken) {
|
||||
var tokenParentKind = token.parent.kind();
|
||||
if (tokenParentKind === TypeScript.SyntaxKind.TypeArgumentList ||
|
||||
tokenParentKind === TypeScript.SyntaxKind.TypeParameterList) {
|
||||
|
||||
if (tokenKind === SyntaxKind.LessThanToken || tokenKind === SyntaxKind.GreaterThanToken) {
|
||||
// If the node owning the token has a type argument list or type parameter list, then
|
||||
// we can effectively assume that a '<' and '>' belong to those lists.
|
||||
if (getTypeArgumentOrTypeParameterList(token.parent)) {
|
||||
return ClassificationTypeNames.punctuation;
|
||||
}
|
||||
}
|
||||
|
||||
if (TypeScript.SyntaxFacts.isBinaryExpressionOperatorToken(tokenKind) ||
|
||||
TypeScript.SyntaxFacts.isPrefixUnaryExpressionOperatorToken(tokenKind)) {
|
||||
return ClassificationTypeNames.operator;
|
||||
if (isPunctuation(token.kind)) {
|
||||
// the '=' in a variable declaration is special cased here.
|
||||
if (token.parent.kind === SyntaxKind.BinaryExpression ||
|
||||
token.parent.kind === SyntaxKind.VariableDeclaration ||
|
||||
token.parent.kind === SyntaxKind.PrefixOperator ||
|
||||
token.parent.kind === SyntaxKind.PostfixOperator ||
|
||||
token.parent.kind === SyntaxKind.ConditionalExpression) {
|
||||
return ClassificationTypeNames.operator;
|
||||
}
|
||||
else {
|
||||
return ClassificationTypeNames.punctuation;
|
||||
}
|
||||
}
|
||||
else if (TypeScript.SyntaxFacts.isAnyPunctuation(tokenKind)) {
|
||||
return ClassificationTypeNames.punctuation;
|
||||
}
|
||||
else if (tokenKind === TypeScript.SyntaxKind.NumericLiteral) {
|
||||
else if (tokenKind === SyntaxKind.NumericLiteral) {
|
||||
return ClassificationTypeNames.numericLiteral;
|
||||
}
|
||||
else if (tokenKind === TypeScript.SyntaxKind.StringLiteral) {
|
||||
else if (tokenKind === SyntaxKind.StringLiteral) {
|
||||
return ClassificationTypeNames.stringLiteral;
|
||||
}
|
||||
else if (tokenKind === TypeScript.SyntaxKind.RegularExpressionLiteral) {
|
||||
// TODO: we shoudl get another classification type for these literals.
|
||||
else if (tokenKind === SyntaxKind.RegularExpressionLiteral) {
|
||||
// TODO: we should get another classification type for these literals.
|
||||
return ClassificationTypeNames.stringLiteral;
|
||||
}
|
||||
else if (tokenKind === TypeScript.SyntaxKind.IdentifierName) {
|
||||
var current: TypeScript.ISyntaxNodeOrToken = token;
|
||||
var parent = token.parent;
|
||||
while (parent.kind() === TypeScript.SyntaxKind.QualifiedName) {
|
||||
current = parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
switch (parent.kind()) {
|
||||
case TypeScript.SyntaxKind.SimplePropertyAssignment:
|
||||
if ((<TypeScript.SimplePropertyAssignmentSyntax>parent).propertyName === token) {
|
||||
return ClassificationTypeNames.identifier;
|
||||
}
|
||||
return;
|
||||
case TypeScript.SyntaxKind.ClassDeclaration:
|
||||
if ((<TypeScript.ClassDeclarationSyntax>parent).identifier === token) {
|
||||
else if (tokenKind === SyntaxKind.Identifier) {
|
||||
switch (token.parent.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if ((<ClassDeclaration>token.parent).name === token) {
|
||||
return ClassificationTypeNames.className;
|
||||
}
|
||||
return;
|
||||
case TypeScript.SyntaxKind.TypeParameter:
|
||||
if ((<TypeScript.TypeParameterSyntax>parent).identifier === token) {
|
||||
case SyntaxKind.TypeParameter:
|
||||
if ((<TypeParameterDeclaration>token.parent).name === token) {
|
||||
return ClassificationTypeNames.typeParameterName;
|
||||
}
|
||||
return;
|
||||
case TypeScript.SyntaxKind.InterfaceDeclaration:
|
||||
if ((<TypeScript.InterfaceDeclarationSyntax>parent).identifier === token) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
if ((<InterfaceDeclaration>token.parent).name === token) {
|
||||
return ClassificationTypeNames.interfaceName;
|
||||
}
|
||||
return;
|
||||
case TypeScript.SyntaxKind.EnumDeclaration:
|
||||
if ((<TypeScript.EnumDeclarationSyntax>parent).identifier === token) {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
if ((<EnumDeclaration>token.parent).name === token) {
|
||||
return ClassificationTypeNames.enumName;
|
||||
}
|
||||
return;
|
||||
case TypeScript.SyntaxKind.ModuleDeclaration:
|
||||
if ((<TypeScript.ModuleDeclarationSyntax>parent).name === current) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if ((<ModuleDeclaration>token.parent).name === token) {
|
||||
return ClassificationTypeNames.moduleName;
|
||||
}
|
||||
return;
|
||||
@@ -4922,19 +4985,18 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function processElement(element: TypeScript.ISyntaxElement) {
|
||||
function processElement(element: Node) {
|
||||
// Ignore nodes that don't intersect the original span to classify.
|
||||
if (!TypeScript.isShared(element) && span.intersectsWith(TypeScript.fullStart(element), TypeScript.fullWidth(element))) {
|
||||
for (var i = 0, n = TypeScript.childCount(element); i < n; i++) {
|
||||
var child = TypeScript.childAt(element, i);
|
||||
if (child) {
|
||||
if (TypeScript.isToken(child)) {
|
||||
classifyToken(<TypeScript.ISyntaxToken>child);
|
||||
}
|
||||
else {
|
||||
// Recurse into our child nodes.
|
||||
processElement(child);
|
||||
}
|
||||
if (span.intersectsWith(element.getFullStart(), element.getFullWidth())) {
|
||||
var children = element.getChildren();
|
||||
for (var i = 0, n = children.length; i < n; i++) {
|
||||
var child = children[i];
|
||||
if (isToken(child)) {
|
||||
classifyToken(child);
|
||||
}
|
||||
else {
|
||||
// Recurse into our child nodes.
|
||||
processElement(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5337,7 +5399,7 @@ module ts {
|
||||
|
||||
/// Classifier
|
||||
export function createClassifier(host: Logger): Classifier {
|
||||
var scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ false);
|
||||
var scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
|
||||
|
||||
/// We do not have a full parser support to know when we should parse a regex or not
|
||||
/// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where
|
||||
|
||||
@@ -174,6 +174,7 @@ module ts {
|
||||
export enum LanguageVersion {
|
||||
EcmaScript3 = 0,
|
||||
EcmaScript5 = 1,
|
||||
EcmaScript6 = 2,
|
||||
}
|
||||
|
||||
export enum ModuleGenTarget {
|
||||
@@ -213,6 +214,7 @@ module ts {
|
||||
switch (languageVersion) {
|
||||
case LanguageVersion.EcmaScript3: return ScriptTarget.ES3
|
||||
case LanguageVersion.EcmaScript5: return ScriptTarget.ES5;
|
||||
case LanguageVersion.EcmaScript6: return ScriptTarget.ES6;
|
||||
default: throw Error("unsupported LanguageVersion value: " + languageVersion);
|
||||
}
|
||||
}
|
||||
@@ -234,6 +236,7 @@ module ts {
|
||||
switch (scriptTarget) {
|
||||
case ScriptTarget.ES3: return LanguageVersion.EcmaScript3;
|
||||
case ScriptTarget.ES5: return LanguageVersion.EcmaScript5;
|
||||
case ScriptTarget.ES6: return LanguageVersion.EcmaScript6;
|
||||
default: throw Error("unsupported ScriptTarget value: " + scriptTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,13 @@ module ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
|
||||
var children = parent.getChildren(sourceFile);
|
||||
var indexOfOpenerToken = children.indexOf(openerToken);
|
||||
Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
|
||||
return children[indexOfOpenerToken + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* The selectedItemIndex could be negative for several reasons.
|
||||
* 1. There are too many arguments for all of the overloads
|
||||
@@ -287,74 +294,51 @@ module ts.SignatureHelp {
|
||||
|
||||
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentInfoOrTypeArgumentInfo: ListItemInfo): SignatureHelpItems {
|
||||
var argumentListOrTypeArgumentList = argumentInfoOrTypeArgumentInfo.list;
|
||||
var parent = <CallExpression>argumentListOrTypeArgumentList.parent;
|
||||
var isTypeParameterHelp = parent.typeArguments && parent.typeArguments.pos === argumentListOrTypeArgumentList.pos;
|
||||
Debug.assert(isTypeParameterHelp || parent.arguments.pos === argumentListOrTypeArgumentList.pos);
|
||||
|
||||
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
|
||||
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
|
||||
var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
|
||||
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
|
||||
var parameters = candidateSignature.parameters;
|
||||
var parameterHelpItems: SignatureHelpParameter[] = parameters.length === 0 ? emptyArray : map(parameters, p => {
|
||||
var displayParts: SymbolDisplayPart[] = [];
|
||||
var signatureHelpParameters: SignatureHelpParameter[];
|
||||
var prefixParts: SymbolDisplayPart[] = [];
|
||||
var suffixParts: SymbolDisplayPart[] = [];
|
||||
|
||||
if (candidateSignature.hasRestParameter && parameters[parameters.length - 1] === p) {
|
||||
displayParts.push(punctuationPart(SyntaxKind.DotDotDotToken));
|
||||
}
|
||||
|
||||
displayParts.push(symbolPart(p.name, p));
|
||||
|
||||
var isOptional = !!(p.valueDeclaration.flags & NodeFlags.QuestionMark);
|
||||
if (isOptional) {
|
||||
displayParts.push(punctuationPart(SyntaxKind.QuestionToken));
|
||||
}
|
||||
|
||||
displayParts.push(punctuationPart(SyntaxKind.ColonToken));
|
||||
displayParts.push(spacePart());
|
||||
|
||||
var typeParts = typeToDisplayParts(typeInfoResolver, typeInfoResolver.getTypeOfSymbol(p), argumentListOrTypeArgumentList);
|
||||
displayParts.push.apply(displayParts, typeParts);
|
||||
|
||||
return {
|
||||
name: p.name,
|
||||
documentation: p.getDocumentationComment(),
|
||||
displayParts: displayParts,
|
||||
isOptional: isOptional
|
||||
};
|
||||
});
|
||||
|
||||
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
|
||||
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
|
||||
|
||||
var prefixParts = callTargetSymbol ? symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : [];
|
||||
|
||||
var separatorParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()];
|
||||
|
||||
// TODO(jfreeman): Constraints?
|
||||
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
||||
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
|
||||
|
||||
for (var i = 0, n = candidateSignature.typeParameters.length; i < n; i++) {
|
||||
if (i) {
|
||||
prefixParts.push.apply(prefixParts, separatorParts);
|
||||
}
|
||||
|
||||
var tp = candidateSignature.typeParameters[i].symbol;
|
||||
prefixParts.push(symbolPart(tp.name, tp));
|
||||
}
|
||||
|
||||
prefixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
if (callTargetDisplayParts) {
|
||||
prefixParts.push.apply(prefixParts, callTargetDisplayParts);
|
||||
}
|
||||
|
||||
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
if (isTypeParameterHelp) {
|
||||
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
|
||||
var typeParameters = candidateSignature.typeParameters;
|
||||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
suffixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
|
||||
var parameterParts = mapToDisplayParts(writer =>
|
||||
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, argumentListOrTypeArgumentList));
|
||||
suffixParts.push.apply(suffixParts, parameterParts);
|
||||
}
|
||||
else {
|
||||
var typeParameterParts = mapToDisplayParts(writer =>
|
||||
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList));
|
||||
prefixParts.push.apply(prefixParts, typeParameterParts);
|
||||
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
var parameters = candidateSignature.parameters;
|
||||
signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
|
||||
suffixParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
|
||||
var suffixParts = [punctuationPart(SyntaxKind.CloseParenToken)];
|
||||
suffixParts.push(punctuationPart(SyntaxKind.ColonToken));
|
||||
suffixParts.push(spacePart());
|
||||
|
||||
var typeParts = typeToDisplayParts(typeInfoResolver, candidateSignature.getReturnType(), argumentListOrTypeArgumentList);
|
||||
suffixParts.push.apply(suffixParts, typeParts);
|
||||
var returnTypeParts = mapToDisplayParts(writer =>
|
||||
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, argumentListOrTypeArgumentList));
|
||||
suffixParts.push.apply(suffixParts, returnTypeParts);
|
||||
|
||||
return {
|
||||
isVariadic: candidateSignature.hasRestParameter,
|
||||
prefixDisplayParts: prefixParts,
|
||||
suffixDisplayParts: suffixParts,
|
||||
separatorDisplayParts: separatorParts,
|
||||
parameters: parameterHelpItems,
|
||||
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
|
||||
parameters: signatureHelpParameters,
|
||||
documentation: candidateSignature.getDocumentationComment()
|
||||
};
|
||||
});
|
||||
@@ -400,12 +384,32 @@ module ts.SignatureHelp {
|
||||
argumentIndex: argumentIndex,
|
||||
argumentCount: argumentCount
|
||||
};
|
||||
|
||||
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
|
||||
var displayParts = mapToDisplayParts(writer =>
|
||||
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, argumentListOrTypeArgumentList));
|
||||
|
||||
var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark);
|
||||
|
||||
return {
|
||||
name: parameter.name,
|
||||
documentation: parameter.getDocumentationComment(),
|
||||
displayParts: displayParts,
|
||||
isOptional: isOptional
|
||||
};
|
||||
}
|
||||
|
||||
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
|
||||
var displayParts = mapToDisplayParts(writer =>
|
||||
typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, argumentListOrTypeArgumentList));
|
||||
|
||||
return {
|
||||
name: typeParameter.symbol.name,
|
||||
documentation: emptyArray,
|
||||
displayParts: displayParts,
|
||||
isOptional: false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getChildListThatStartsWithOpenerToken(parent: Node, openerToken: Node, sourceFile: SourceFile): Node {
|
||||
var children = parent.getChildren(sourceFile);
|
||||
var indexOfOpenerToken = children.indexOf(openerToken);
|
||||
return children[indexOfOpenerToken + 1];
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ module TypeScript.Scanner {
|
||||
var lastTokenInfo = { leadingTriviaWidth: -1, width: -1 };
|
||||
var lastTokenInfoTokenID: number = -1;
|
||||
|
||||
var triviaScanner = createScannerInternal(ts.ScriptTarget.ES5, SimpleText.fromString(""), () => { });
|
||||
var triviaScanner = createScannerInternal(ts.ScriptTarget.Latest, SimpleText.fromString(""), () => { });
|
||||
|
||||
interface IScannerToken extends ISyntaxToken {
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ module TypeScript {
|
||||
if (languageVersion === ts.ScriptTarget.ES3) {
|
||||
return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierStart);
|
||||
}
|
||||
else if (languageVersion === ts.ScriptTarget.ES5) {
|
||||
else if (languageVersion >= ts.ScriptTarget.ES5) {
|
||||
return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierStart);
|
||||
}
|
||||
else {
|
||||
@@ -96,7 +96,7 @@ module TypeScript {
|
||||
if (languageVersion === ts.ScriptTarget.ES3) {
|
||||
return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierPart);
|
||||
}
|
||||
else if (languageVersion === ts.ScriptTarget.ES5) {
|
||||
else if (languageVersion >= ts.ScriptTarget.ES5) {
|
||||
return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierPart);
|
||||
}
|
||||
else {
|
||||
|
||||
+24
-12
@@ -75,14 +75,14 @@ module ts {
|
||||
* position >= start and (position < end or (position === end && token is keyword or identifier))
|
||||
*/
|
||||
export function getTouchingWord(sourceFile: SourceFile, position: number): Node {
|
||||
return getTouchingToken(sourceFile, position, isWord);
|
||||
return getTouchingToken(sourceFile, position, n => isWord(n.kind));
|
||||
}
|
||||
|
||||
/* Gets the token whose text has range [start, end) and position >= start
|
||||
* and (position < end or (position === end && token is keyword or identifier or numeric\string litera))
|
||||
*/
|
||||
export function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node {
|
||||
return getTouchingToken(sourceFile, position, isPropertyName);
|
||||
return getTouchingToken(sourceFile, position, n => isPropertyName(n.kind));
|
||||
}
|
||||
|
||||
/** Returns the token if position is in [start, end) or if position === end and includeItemAtEndPosition(token) === true */
|
||||
@@ -243,23 +243,35 @@ module ts {
|
||||
return n.kind !== SyntaxKind.SyntaxList || n.getChildCount() !== 0;
|
||||
}
|
||||
|
||||
export function getTypeArgumentOrTypeParameterList(node: Node): NodeArray<Node> {
|
||||
if (node.kind === SyntaxKind.TypeReference || node.kind === SyntaxKind.CallExpression) {
|
||||
return (<CallExpression>node).typeArguments;
|
||||
}
|
||||
|
||||
if (isAnyFunction(node) || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.InterfaceDeclaration) {
|
||||
return (<FunctionDeclaration>node).typeParameters;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isToken(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken;
|
||||
}
|
||||
|
||||
function isWord(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.Identifier || isKeyword(kind);
|
||||
}
|
||||
|
||||
function isPropertyName(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.StringLiteral || kind === SyntaxKind.NumericLiteral || isWord(kind);
|
||||
}
|
||||
|
||||
export function isComment(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.SingleLineCommentTrivia || kind === SyntaxKind.MultiLineCommentTrivia;
|
||||
}
|
||||
|
||||
function isKeyword(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstKeyword && n.kind <= SyntaxKind.LastKeyword;
|
||||
}
|
||||
|
||||
function isWord(n: Node): boolean {
|
||||
return n.kind === SyntaxKind.Identifier || isKeyword(n);
|
||||
}
|
||||
|
||||
function isPropertyName(n: Node): boolean {
|
||||
return n.kind === SyntaxKind.StringLiteral || n.kind === SyntaxKind.NumericLiteral || isWord(n);
|
||||
export function isPunctuation(kind: SyntaxKind): boolean {
|
||||
return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user