merge with master

This commit is contained in:
Vladimir Matveev
2014-10-24 15:44:12 -07:00
357 changed files with 27177 additions and 10018 deletions
+81 -36
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -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",
+4 -2
View File
@@ -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}'." },
+48 -4
View File
@@ -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
View File
@@ -4,8 +4,11 @@
/// <reference path="parser.ts"/>
module ts {
interface EmitTextWriter extends SymbolWriter {
interface EmitTextWriter {
write(s: string): void;
writeLine(): void;
increaseIndent(): void;
decreaseIndent(): void;
getText(): string;
rawWrite(s: string): void;
writeLiteral(s: string): void;
@@ -15,6 +18,9 @@ module ts {
getIndent(): number;
}
interface EmitTextWriterWithSymbolWriter extends EmitTextWriter, SymbolWriter{
}
var indentStrings: string[] = ["", " "];
export function getIndentString(level: number) {
if (indentStrings[level] === undefined) {
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+13 -56
View File
@@ -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
View File
@@ -146,7 +146,7 @@ module FourSlash {
function convertGlobalOptionsToCompilationSettings(globalOptions: { [idx: string]: string }): ts.CompilationSettings {
var settings: ts.CompilationSettings = {};
// Convert all property in globalOptions into ts.CompilationSettings
// Convert all property in globalOptions into ts.CompilationSettings
for (var prop in globalOptions) {
if (globalOptions.hasOwnProperty(prop)) {
switch (prop) {
@@ -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
View File
@@ -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);
}
}
+1 -1
View File
@@ -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 */
+10
View File
@@ -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;
});
});
}
}
-7
View File
@@ -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
View File
@@ -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);
}
}
-73
View File
@@ -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
View File
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() + " {");
+1 -1
View File
@@ -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);
+1 -5
View File
@@ -512,7 +512,7 @@ module TypeScript {
for (var i = 0, n = fileNames.length; i < n; i++) {
var fileName = fileNames[i];
var document = this.getDocument(fileNames[i]);
var document = this.getDocument(fileName);
sharedEmitter = this._emitDocumentDeclarations(document, emitOptions,
file => emitOutput.outputFiles.push(file), sharedEmitter);
@@ -578,7 +578,6 @@ module TypeScript {
var sourceUnit = document.sourceUnit();
Debug.assert(this._shouldEmit(document));
var typeScriptFileName = document.fileName;
if (!emitter) {
var javaScriptFileName = this.mapOutputFileName(document, emitOptions, TypeScriptCompiler.mapToJSFileName);
var outFile = new TextWriter(javaScriptFileName, this.writeByteOrderMarkForDocument(document), OutputFileType.JavaScript);
@@ -799,8 +798,6 @@ module TypeScript {
}
private extractResolutionContextFromAST(resolver: PullTypeResolver, ast: ISyntaxElement, document: Document, propagateContextualTypes: boolean): { ast: ISyntaxElement; enclosingDecl: PullDecl; resolutionContext: PullTypeResolutionContext; inContextuallyTypedAssignment: boolean; inWithBlock: boolean; } {
var scriptName = document.fileName;
var enclosingDecl: PullDecl = null;
var enclosingDeclAST: ISyntaxElement = null;
var inContextuallyTypedAssignment = false;
@@ -981,7 +978,6 @@ module TypeScript {
case SyntaxKind.ReturnStatement:
if (propagateContextualTypes) {
var returnStatement = <ReturnStatementSyntax>current;
var contextualType: PullTypeSymbol = null;
if (enclosingDecl && (enclosingDecl.kind & PullElementKind.SomeFunction)) {
-6
View File
@@ -7,12 +7,6 @@ module TypeScript {
}
export function integerMultiplyLow32Bits(n1: number, n2: number): number {
var n1Low16 = n1 & 0x0000ffff;
var n1High16 = n1 >>> 16;
var n2Low16 = n2 & 0x0000ffff;
var n2High16 = n2 >>> 16;
var resultLow32 = (((n1 & 0xffff0000) * n2) >>> 0) + (((n1 & 0x0000ffff) * n2) >>> 0) >>> 0;
return resultLow32;
}
+6 -1
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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);
}
}
+68 -64
View File
@@ -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];
}
}
+1 -1
View File
@@ -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 {
}
-1
View File
@@ -84,7 +84,6 @@ module TypeScript {
private cacheSyntaxTreeInfo(): void {
// If we're not keeping around the syntax tree, store the diagnostics and line
// map so they don't have to be recomputed.
var sourceUnit = this.sourceUnit();
var firstToken = firstSyntaxTreeToken(this);
var leadingTrivia = firstToken.leadingTrivia(this.text);
+2 -2
View File
@@ -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
View File
@@ -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;
}
}