Merge branch 'master' into getOccsForModifiers

This commit is contained in:
Daniel Rosenwasser 2014-11-25 15:03:28 -08:00
commit d373dc8a99
585 changed files with 14683 additions and 7435 deletions

1
.gitignore vendored
View File

@ -39,4 +39,5 @@ scripts/debug.bat
scripts/run.bat
scripts/word2md.js
scripts/ior.js
scripts/*.js.map
coverage/

2011
bin/tsc.js

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ module ts {
return ModuleInstanceState.NonInstantiated;
}
// 2. const enum declarations don't make module instantiated
else if (node.kind === SyntaxKind.EnumDeclaration && isConstEnumDeclaration(<EnumDeclaration>node)) {
else if (isConstEnumDeclaration(node)) {
return ModuleInstanceState.ConstEnumOnly;
}
// 3. non - exported import declarations
@ -125,9 +125,9 @@ module ts {
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
file.semanticErrors.push(createDiagnosticForNode(declaration.name, message, getDisplayName(declaration)));
file.semanticDiagnostics.push(createDiagnosticForNode(declaration.name, message, getDisplayName(declaration)));
});
file.semanticErrors.push(createDiagnosticForNode(node.name, message, getDisplayName(node)));
file.semanticDiagnostics.push(createDiagnosticForNode(node.name, message, getDisplayName(node)));
symbol = createSymbol(0, name);
}
@ -148,7 +148,7 @@ module ts {
if (node.name) {
node.name.parent = node;
}
file.semanticErrors.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
file.semanticDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
symbol.exports[prototypeSymbol.name] = prototypeSymbol;
@ -439,7 +439,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.EnumDeclaration:
if (isConstEnumDeclaration(<EnumDeclaration>node)) {
if (isConst(node)) {
bindDeclaration(<Declaration>node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false);
}
else {

View File

@ -81,10 +81,11 @@ module ts {
getTypeCount: () => typeCount,
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
emitFiles: invokeEmitter,
getDiagnostics,
getDeclarationDiagnostics,
getGlobalDiagnostics,
checkProgram,
invokeEmitter,
getParentOfSymbol,
getNarrowedTypeOfSymbol,
getDeclaredTypeOfSymbol,
@ -885,13 +886,13 @@ module ts {
if (accessibleSymbolChain) {
var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0]);
if (!hasAccessibleDeclarations) {
return {
return <SymbolAccessiblityResult>{
accessibility: SymbolAccessibility.NotAccessible,
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, SymbolFlags.Namespace) : undefined,
};
}
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible: hasAccessibleDeclarations.aliasesToMakeVisible };
return hasAccessibleDeclarations;
}
// If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
@ -948,12 +949,12 @@ module ts {
(declaration.kind === SyntaxKind.SourceFile && isExternalModule(<SourceFile>declaration));
}
function hasVisibleDeclarations(symbol: Symbol): { aliasesToMakeVisible?: ImportDeclaration[]; } {
function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult {
var aliasesToMakeVisible: ImportDeclaration[];
if (forEach(symbol.declarations, declaration => !getIsDeclarationVisible(declaration))) {
return undefined;
}
return { aliasesToMakeVisible };
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible };
function getIsDeclarationVisible(declaration: Declaration) {
if (!isDeclarationVisible(declaration)) {
@ -982,14 +983,33 @@ module ts {
}
}
function isImportDeclarationEntityNameReferenceDeclarationVisibile(entityName: EntityName): SymbolAccessiblityResult {
function isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult {
// get symbol of the first identifier of the entityName
var meaning: SymbolFlags;
if (entityName.parent.kind === SyntaxKind.TypeQuery) {
// Typeof value
meaning = SymbolFlags.Value | SymbolFlags.ExportValue;
}
else if (entityName.kind === SyntaxKind.QualifiedName ||
entityName.parent.kind === SyntaxKind.ImportDeclaration) {
// Left identifier from type reference or TypeAlias
// Entity name of the import declaration
meaning = SymbolFlags.Namespace;
}
else {
// Type Reference or TypeAlias entity = Identifier
meaning = SymbolFlags.Type;
}
var firstIdentifier = getFirstIdentifier(entityName);
var symbolOfNameSpace = resolveName(entityName.parent, (<Identifier>firstIdentifier).text, SymbolFlags.Namespace, Diagnostics.Cannot_find_name_0, firstIdentifier);
var symbol = resolveName(enclosingDeclaration, (<Identifier>firstIdentifier).text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
// Verify if the symbol is accessible
var hasNamespaceDeclarationsVisibile = hasVisibleDeclarations(symbolOfNameSpace);
return hasNamespaceDeclarationsVisibile ?
{ accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible: hasNamespaceDeclarationsVisibile.aliasesToMakeVisible } :
{ accessibility: SymbolAccessibility.NotAccessible, errorSymbolName: declarationNameToString(<Identifier>firstIdentifier) };
return hasVisibleDeclarations(symbol) || <SymbolVisibilityResult>{
accessibility: SymbolAccessibility.NotAccessible,
errorSymbolName: getTextOfNode(firstIdentifier),
errorNode: firstIdentifier
};
}
function releaseStringWriter(writer: StringSymbolWriter) {
@ -1601,6 +1621,7 @@ module ts {
case SyntaxKind.IndexSignature:
case SyntaxKind.Parameter:
case SyntaxKind.ModuleBlock:
case SyntaxKind.TypeParameter:
return isDeclarationVisible(node.parent);
// Source file is always visible
@ -1784,7 +1805,7 @@ module ts {
}
else {
// If there are no specified types, try to infer it from the body of the get accessor if it exists.
if (getter) {
if (getter && getter.body) {
type = getReturnTypeFromBody(getter);
}
// Otherwise, fall back to 'any'.
@ -7531,10 +7552,13 @@ module ts {
// for (var VarDecl in Expr) Statement
// VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
// and Expr must be an expression of type Any, an object type, or a type parameter type.
if (node.declaration) {
checkVariableDeclaration(node.declaration);
if (node.declaration.type) {
error(node.declaration, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
if (node.declarations) {
if (node.declarations.length >= 1) {
var decl = node.declarations[0];
checkVariableDeclaration(decl);
if (decl.type) {
error(decl, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
}
}
}
@ -7983,7 +8007,7 @@ module ts {
var enumType = getDeclaredTypeOfSymbol(enumSymbol);
var autoValue = 0;
var ambient = isInAmbientContext(node);
var enumIsConst = isConstEnumDeclaration(node);
var enumIsConst = isConst(node);
forEach(node.members, member => {
// TODO(jfreeman): Check that it is not a computed name
@ -8154,10 +8178,10 @@ module ts {
var firstDeclaration = getDeclarationOfKind(enumSymbol, node.kind);
if (node === firstDeclaration) {
if (enumSymbol.declarations.length > 1) {
var enumIsConst = isConstEnumDeclaration(node);
var enumIsConst = isConst(node);
// check that const is placed\omitted on all enum declarations
forEach(enumSymbol.declarations, decl => {
if (isConstEnumDeclaration(<EnumDeclaration>decl) !== enumIsConst) {
if (isConstEnumDeclaration(decl) !== enumIsConst) {
error(decl.name, Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
}
});
@ -8522,6 +8546,12 @@ module ts {
return getSortedDiagnostics();
}
function getDeclarationDiagnostics(targetSourceFile: SourceFile): Diagnostic[] {
var resolver = createResolver();
checkSourceFile(targetSourceFile);
return ts.getDeclarationDiagnostics(program, resolver, targetSourceFile);
}
function getGlobalDiagnostics(): Diagnostic[] {
return filter(getSortedDiagnostics(), d => !d.file);
}
@ -9115,8 +9145,8 @@ module ts {
getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags);
}
function invokeEmitter(targetSourceFile?: SourceFile) {
var resolver: EmitResolver = {
function createResolver(): EmitResolver {
return {
getProgram: () => program,
getLocalNameOfContainer,
getExpressionNamePrefix,
@ -9132,9 +9162,13 @@ module ts {
writeTypeAtLocation,
writeReturnTypeOfSignatureDeclaration,
isSymbolAccessible,
isImportDeclarationEntityNameReferenceDeclarationVisibile,
isEntityNameVisible,
getConstantValue,
};
}
function invokeEmitter(targetSourceFile?: SourceFile) {
var resolver = createResolver();
checkProgram();
return emitFiles(resolver, targetSourceFile);
}
@ -9143,7 +9177,7 @@ module ts {
// Bind all source files and propagate errors
forEach(program.getSourceFiles(), file => {
bindSourceFile(file);
forEach(file.semanticErrors, addDiagnostic);
forEach(file.semanticDiagnostics, addDiagnostic);
});
// Initialize global symbol table
forEach(program.getSourceFiles(), file => {

View File

@ -459,6 +459,10 @@ module ts {
return normalizedPathComponents(path, rootLength);
}
export function getNormalizedAbsolutePath(filename: string, currentDirectory: string) {
return getNormalizedPathFromPathComponents(getNormalizedPathComponents(filename, currentDirectory));
}
export function getNormalizedPathFromPathComponents(pathComponents: string[]) {
if (pathComponents && pathComponents.length) {
return pathComponents[0] + pathComponents.slice(1).join(directorySeparator);

View File

@ -124,7 +124,8 @@ module ts {
Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." },
Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." },
Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." },
An_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },
An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },
yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." },
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." },
@ -275,27 +276,16 @@ module ts {
Type_alias_name_cannot_be_0: { code: 2457, category: DiagnosticCategory.Error, key: "Type alias name cannot be '{0}'" },
An_AMD_module_cannot_have_multiple_name_assignments: { code: 2458, category: DiagnosticCategory.Error, key: "An AMD module cannot have multiple name assignments." },
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}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4003, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4005, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4006, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'." },
Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4007, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4008, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'." },
Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4009, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: { code: 4010, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'." },
Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4011, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: { code: 4012, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of public method from exported class has or is using private name '{1}'." },
Type_parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4013, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: { code: 4014, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of method from exported interface has or is using private name '{1}'." },
Type_parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: { code: 4015, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'." },
Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: { code: 4016, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported function has or is using private name '{1}'." },
Implements_clause_of_exported_class_0_has_or_is_using_name_1_from_private_module_2: { code: 4017, category: DiagnosticCategory.Error, key: "Implements clause of exported class '{0}' has or is using name '{1}' from private module '{2}'." },
Extends_clause_of_exported_class_0_has_or_is_using_name_1_from_private_module_2: { code: 4018, category: DiagnosticCategory.Error, key: "Extends clause of exported class '{0}' has or is using name '{1}' from private module '{2}'." },
Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 4019, category: DiagnosticCategory.Error, key: "Implements clause of exported class '{0}' has or is using private name '{1}'." },
Extends_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 4020, category: DiagnosticCategory.Error, key: "Extends clause of exported class '{0}' has or is using private name '{1}'." },
Extends_clause_of_exported_interface_0_has_or_is_using_name_1_from_private_module_2: { code: 4021, category: DiagnosticCategory.Error, key: "Extends clause of exported interface '{0}' has or is using name '{1}' from private module '{2}'." },
Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: { code: 4022, category: DiagnosticCategory.Error, key: "Extends clause of exported interface '{0}' has or is using private name '{1}'." },
Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4023, category: DiagnosticCategory.Error, key: "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named." },
Exported_variable_0_has_or_is_using_name_1_from_private_module_2: { code: 4024, category: DiagnosticCategory.Error, key: "Exported variable '{0}' has or is using name '{1}' from private module '{2}'." },
@ -353,8 +343,6 @@ module ts {
Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4076, category: DiagnosticCategory.Error, key: "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named." },
Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: { code: 4077, category: DiagnosticCategory.Error, key: "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'." },
Parameter_0_of_exported_function_has_or_is_using_private_name_1: { code: 4078, category: DiagnosticCategory.Error, key: "Parameter '{0}' of exported function has or is using private name '{1}'." },
Exported_type_alias_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4079, category: DiagnosticCategory.Error, key: "Exported type alias '{0}' has or is using name '{1}' from external module {2} but cannot be named." },
Exported_type_alias_0_has_or_is_using_name_1_from_private_module_2: { code: 4080, category: DiagnosticCategory.Error, key: "Exported type alias '{0}' has or is using name '{1}' from private module '{2}'." },
Exported_type_alias_0_has_or_is_using_private_name_1: { code: 4081, category: DiagnosticCategory.Error, key: "Exported type alias '{0}' has or is using private name '{1}'." },
Enum_declarations_must_all_be_const_or_non_const: { code: 4082, category: DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 4083, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression.", isEarly: true },

View File

@ -487,10 +487,13 @@
"category": "Error",
"code": 1161
},
"An object member cannot be declared optional.": {
"category": "Error",
"code": 1160
"code": 1162
},
"'yield' expression must be contained_within a generator declaration.": {
"category": "Error",
"code": 1163
},
"Duplicate identifier '{0}'.": {
@ -1098,78 +1101,38 @@
"category": "Error",
"code": 4000
},
"Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4001
},
"Type parameter '{0}' of exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4002
},
"Type parameter '{0}' of exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4003
},
"Type parameter '{0}' of exported interface has or is using private name '{1}'.": {
"category": "Error",
"code": 4004
},
"Type parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4005
},
"Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.": {
"category": "Error",
"code": 4006
},
"Type parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4007
},
"Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.": {
"category": "Error",
"code": 4008
},
"Type parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4009
},
"Type parameter '{0}' of public static method from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4010
},
"Type parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4011
},
"Type parameter '{0}' of public method from exported class has or is using private name '{1}'.": {
"category": "Error",
"code": 4012
},
"Type parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4013
},
"Type parameter '{0}' of method from exported interface has or is using private name '{1}'.": {
"category": "Error",
"code": 4014
},
"Type parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4015
},
"Type parameter '{0}' of exported function has or is using private name '{1}'.": {
"category": "Error",
"code": 4016
},
"Implements clause of exported class '{0}' has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4017
},
"Extends clause of exported class '{0}' has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4018
},
"Implements clause of exported class '{0}' has or is using private name '{1}'.": {
"category": "Error",
"code": 4019
@ -1178,10 +1141,6 @@
"category": "Error",
"code": 4020
},
"Extends clause of exported interface '{0}' has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4021
},
"Extends clause of exported interface '{0}' has or is using private name '{1}'.": {
"category": "Error",
"code": 4022
@ -1410,14 +1369,6 @@
"category": "Error",
"code": 4078
},
"Exported type alias '{0}' has or is using name '{1}' from external module {2} but cannot be named.": {
"category": "Error",
"code": 4079
},
"Exported type alias '{0}' has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4080
},
"Exported type alias '{0}' has or is using private name '{1}'.": {
"category": "Error",
"code": 4081

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -931,12 +931,12 @@ module ts {
value = 0;
}
tokenValue = "" + value;
return SyntaxKind.NumericLiteral;
return token = SyntaxKind.NumericLiteral;
}
// Try to parse as an octal
if (pos + 1 < len && isOctalDigit(text.charCodeAt(pos + 1))) {
tokenValue = "" + scanOctalDigits();
return SyntaxKind.NumericLiteral;
return token = SyntaxKind.NumericLiteral;
}
// This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
// can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being

View File

@ -367,7 +367,7 @@ module ts {
}
else {
var emitStart = new Date().getTime();
var emitOutput = checker.invokeEmitter();
var emitOutput = checker.emitFiles();
var emitErrors = emitOutput.diagnostics;
exitStatus = emitOutput.emitResultStatus;
var reportStart = new Date().getTime();

View File

@ -183,6 +183,7 @@ module ts {
ConditionalExpression,
TemplateExpression,
TemplateSpan,
YieldExpression,
OmittedExpression,
// Element
Block,
@ -256,40 +257,60 @@ module ts {
}
export const enum NodeFlags {
Export = 0x00000001, // Declarations
Ambient = 0x00000002, // Declarations
QuestionMark = 0x00000004, // Parameter/Property/Method
Rest = 0x00000008, // Parameter
Public = 0x00000010, // Property/Method
Private = 0x00000020, // Property/Method
Protected = 0x00000040, // Property/Method
Static = 0x00000080, // Property/Method
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
Export = 0x00000001, // Declarations
Ambient = 0x00000002, // Declarations
QuestionMark = 0x00000004, // Parameter/Property/Method
Rest = 0x00000008, // Parameter
Public = 0x00000010, // Property/Method
Private = 0x00000020, // Property/Method
Protected = 0x00000040, // Property/Method
Static = 0x00000080, // Property/Method
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
OctalLiteral = 0x00002000,
Generator = 0x00004000,
YieldStar = 0x00008000,
Modifier = Export | Ambient | Public | Private | Protected | Static,
AccessibilityModifier = Public | Private | Protected,
BlockScoped = Let | Const
}
export const enum ParserContextFlags {
// Set if this node was parsed in strict mode. Used for grammar error checks, as well as
// checking if the node can be reused in incremental settings.
StrictMode = 1 << 0,
DisallowIn = 1 << 1,
Yield = 1 << 2,
GeneratorParameter = 1 << 3,
}
export interface Node extends TextRange {
kind: SyntaxKind;
flags: NodeFlags;
// Specific context the parser was in when this node was created. Normally undefined.
// Only set when the parser was in some interesting context (like async/yield).
parserContextFlags?: ParserContextFlags;
id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding)
symbol?: Symbol; // Symbol declared by node (initialized by binding)
locals?: SymbolTable; // Locals associated with node (initialized by binding)
nextContainer?: Node; // Next container in declaration order (initialized by binding)
localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
modifiers?: ModifiersArray; // Array of modifiers
}
export interface NodeArray<T> extends Array<T>, TextRange {
hasTrailingComma?: boolean;
}
export interface ModifiersArray extends Array<Node> {
flags: number;
}
export interface Identifier extends Node {
text: string; // Text of identifier (with escapes converted to characters)
}
@ -321,6 +342,9 @@ module ts {
export interface TypeParameterDeclaration extends Declaration {
name: Identifier;
constraint?: TypeNode;
// For error recovery purposes.
expression?: Expression;
}
export interface SignatureDeclaration extends Declaration, ParsedSignature { }
@ -416,6 +440,10 @@ module ts {
operator: SyntaxKind;
operand: Expression;
}
export interface YieldExpression extends Expression {
expression: Expression;
}
export interface BinaryExpression extends Expression {
left: Expression;
@ -535,7 +563,7 @@ module ts {
}
export interface ForInStatement extends IterationStatement {
declaration?: VariableDeclaration;
declarations?: NodeArray<VariableDeclaration>;
variable?: Expression;
expression: Expression;
}
@ -580,6 +608,7 @@ module ts {
export interface CatchBlock extends Block {
variable: Identifier;
type?: TypeNode;
}
export interface ClassDeclaration extends Declaration {
@ -644,8 +673,17 @@ module ts {
amdDependencies: string[];
amdModuleName: string;
referencedFiles: FileReference[];
syntacticErrors: Diagnostic[];
semanticErrors: Diagnostic[];
semanticDiagnostics: Diagnostic[];
// Parse errors refer specifically to things the parser could not understand at all (like
// missing tokens, or tokens it didn't know how to deal with). Grammar errors are for
// things the parser understood, but either the ES6 or TS grammars do not allow (like
// putting an 'public' modifier on a 'class declaration').
parseDiagnostics: Diagnostic[];
grammarDiagnostics: Diagnostic[];
// Returns all
getSyntacticDiagnostics(): Diagnostic[];
hasNoDefaultLib: boolean;
externalModuleIndicator: Node; // The first node that causes this file to be an external module
nodeCount: number;
@ -708,13 +746,14 @@ module ts {
export interface TypeChecker {
getProgram(): Program;
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getNodeCount(): number;
getIdentifierCount(): number;
getSymbolCount(): number;
getTypeCount(): number;
checkProgram(): void;
invokeEmitter(targetSourceFile?: SourceFile): EmitResult;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
getParentOfSymbol(symbol: Symbol): Symbol;
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
@ -734,11 +773,11 @@ module ts {
getAugmentedPropertiesOfType(type: Type): Symbol[];
getRootSymbols(symbol: Symbol): Symbol[];
getContextualType(node: Node): Type;
getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature;
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature;
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
isUndefinedSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
isArgumentsSymbol(symbol: Symbol): boolean;
isEmitBlocked(sourceFile?: SourceFile): boolean;
// Returns the constant value of this enum member, or 'undefined' if the enum member has a computed value.
getEnumMemberValue(node: EnumMember): number;
@ -805,11 +844,15 @@ module ts {
CannotBeNamed
}
export interface SymbolAccessiblityResult {
export interface SymbolVisibilityResult {
accessibility: SymbolAccessibility;
errorSymbolName?: string // Optional symbol name that results in error
errorModuleName?: string // If the symbol is not visible from module, module's name
aliasesToMakeVisible?: ImportDeclaration[]; // aliases that need to have this symbol visible
errorSymbolName?: string; // Optional symbol name that results in error
errorNode?: Node; // optional node that results in error
}
export interface SymbolAccessiblityResult extends SymbolVisibilityResult {
errorModuleName?: string // If the symbol is not visible from module, module's name
}
export interface EmitResolver {
@ -827,7 +870,7 @@ module ts {
writeTypeAtLocation(location: Node, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult;
isImportDeclarationEntityNameReferenceDeclarationVisibile(entityName: EntityName): SymbolAccessiblityResult;
isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult;
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
getConstantValue(node: PropertyAccess | IndexedAccess): number;
isEmitBlocked(sourceFile?: SourceFile): boolean;

View File

@ -2223,7 +2223,7 @@ module FourSlash {
if (errs.length > 0) {
throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n'));
}
checker.invokeEmitter();
checker.emitFiles();
result = result || ''; // Might have an empty fourslash file
// Compile and execute the test

View File

@ -806,7 +806,7 @@ module Harness {
// only emit if there weren't parse errors
var emitResult: ts.EmitResult;
if (!isEmitBlocked) {
emitResult = checker.invokeEmitter();
emitResult = checker.emitFiles();
}
var errors: HarnessDiagnostic[] = [];
@ -866,7 +866,7 @@ module Harness {
var sourceFileName: string;
if (ts.isExternalModule(sourceFile) || !options.out) {
if (options.outDir) {
var sourceFilePath = ts.getNormalizedPathFromPathComponents(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram));
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, result.currentDirectoryForProgram);
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
}

View File

@ -17,6 +17,7 @@ interface ProjectRunnerTestCase {
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
runTest?: boolean; // Run the resulting test
bug?: string; // If there is any bug associated with this test case
noResolve?: boolean;
}
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
@ -131,7 +132,7 @@ class ProjectRunner extends RunnerBase {
if (!errors.length) {
var checker = program.getTypeChecker(/*fullTypeCheck*/ true);
errors = checker.getDiagnostics();
var emitResult = checker.invokeEmitter();
var emitResult = checker.emitFiles();
errors = ts.concatenate(errors, emitResult.diagnostics);
sourceMapData = emitResult.sourceMaps;
@ -162,7 +163,8 @@ class ProjectRunner extends RunnerBase {
outDir: testCase.outDir,
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? sys.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? sys.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind
module: moduleKind,
noResolve: testCase.noResolve
};
}
@ -272,16 +274,40 @@ class ProjectRunner extends RunnerBase {
}
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
var inputDtsSourceFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
sourceFile => Harness.Compiler.isDTS(sourceFile.filename)),
sourceFile => {
return { emittedFileName: sourceFile.filename, code: sourceFile.text };
});
var allInputFiles: { emittedFileName: string; code: string; }[] = [];
var compilerOptions = compilerResult.program.getCompilerOptions();
var compilerHost = compilerResult.program.getCompilerHost();
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
if (Harness.Compiler.isDTS(sourceFile.filename)) {
allInputFiles.unshift({ emittedFileName: sourceFile.filename, code: sourceFile.text });
}
else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) {
if (compilerOptions.outDir) {
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory());
sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), "");
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath));
}
else {
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.filename);
}
var outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName));
}
else {
var outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts";
var outputDtsFile = findOutpuDtsFile(outputDtsFileName);
if (!ts.contains(allInputFiles, outputDtsFile)) {
allInputFiles.unshift(outputDtsFile);
}
}
});
var ouputDtsFiles = ts.filter(compilerResult.outputFiles, ouputFile => Harness.Compiler.isDTS(ouputFile.emittedFileName));
var allInputFiles = inputDtsSourceFiles.concat(ouputDtsFiles);
return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile);
function findOutpuDtsFile(fileName: string) {
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
}
function getInputFiles() {
return ts.map(allInputFiles, outputFile => outputFile.emittedFileName);
}

View File

@ -252,7 +252,7 @@ module ts.formatting {
rulesProvider: RulesProvider,
requestKind: FormattingRequestKind): TextChange[] {
var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.syntacticErrors, originalRange);
var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.getSyntacticDiagnostics(), originalRange);
// formatting context is used by rules provider
var formattingContext = new FormattingContext(sourceFile, requestKind);

View File

@ -234,8 +234,11 @@ module ts.NavigationBar {
return createItem(node, getTextOfNode((<FunctionLikeDeclaration>node).name), ts.ScriptElementKind.functionElement);
case SyntaxKind.VariableDeclaration:
if (node.flags & NodeFlags.Const) {
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.constantElement);
if (isConst(node)) {
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.constElement);
}
else if (isLet(node)) {
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.letElement);
}
else {
return createItem(node, getTextOfNode((<VariableDeclaration>node).name), ts.ScriptElementKind.variableElement);

View File

@ -714,14 +714,20 @@ module ts {
class SourceFileObject extends NodeObject implements SourceFile {
public filename: string;
public text: string;
public getLineAndCharacterFromPosition(position: number): { line: number; character: number } { return null; }
public getPositionFromLineAndCharacter(line: number, character: number): number { return -1; }
public getLineStarts(): number[] { return undefined; }
// These methods will have their implementation provided by the implementation the
// compiler actually exports off of SourceFile.
public getLineAndCharacterFromPosition: (position: number) => LineAndCharacter;
public getPositionFromLineAndCharacter: (line: number, character: number) => number;
public getLineStarts: () => number[];
public getSyntacticDiagnostics: () => Diagnostic[];
public amdDependencies: string[];
public amdModuleName: string;
public referencedFiles: FileReference[];
public syntacticErrors: Diagnostic[];
public semanticErrors: Diagnostic[];
public parseDiagnostics: Diagnostic[];
public grammarDiagnostics: Diagnostic[];
public semanticDiagnostics: Diagnostic[];
public hasNoDefaultLib: boolean;
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
public nodeCount: number;
@ -884,9 +890,6 @@ module ts {
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems;
// Obsolete. Use getSignatureHelpItems instead.
getSignatureAtPosition(fileName: string, position: number): SignatureInfo;
getRenameInfo(fileName: string, position: number): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
@ -908,44 +911,11 @@ module ts {
getEmitOutput(fileName: string): EmitOutput;
getSourceFile(filename: string): SourceFile;
dispose(): void;
}
export interface SignatureInfo {
actual: ActualSignatureInfo;
formal: FormalSignatureItemInfo[]; // Formal signatures
activeFormal: number; // Index of the "best match" formal signature
}
export interface FormalSignatureItemInfo {
signatureInfo: string;
typeParameters: FormalTypeParameterInfo[];
parameters: FormalParameterInfo[]; // Array of parameters
docComment: string; // Help for the signature
}
export interface FormalTypeParameterInfo {
name: string; // Type parameter name
docComment: string; // Comments that contain help for the parameter
minChar: number; // minChar for parameter info in the formal signature info string
limChar: number; // lim char for parameter info in the formal signature info string
}
export interface FormalParameterInfo {
name: string; // Parameter name
isVariable: boolean; // true if parameter is var args
docComment: string; // Comments that contain help for the parameter
minChar: number; // minChar for parameter info in the formal signature info string
limChar: number; // lim char for parameter info in the formal signature info string
}
export interface ActualSignatureInfo {
parameterMinChar: number;
parameterLimChar: number;
currentParameterIsTypeParameter: boolean; // current parameter is a type argument or a normal argument
currentParameter: number; // Index of active parameter in "parameters" or "typeParamters" array
}
export interface ClassifiedSpan {
textSpan: TextSpan;
classificationType: string; // ClassificationTypeNames
@ -1175,7 +1145,7 @@ module ts {
}
export interface Classifier {
getClassificationsForLine(text: string, lexState: EndOfLineState): ClassificationResult;
getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): ClassificationResult;
}
export interface DocumentRegistry {
@ -1272,7 +1242,9 @@ module ts {
static alias = "alias";
static constantElement = "constant";
static constElement = "const";
static letElement = "let";
}
export class ScriptElementKindModifier {
@ -2093,8 +2065,12 @@ module ts {
localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages();
}
function getCanonicalFileName(filename: string) {
return useCaseSensitivefilenames ? filename : filename.toLowerCase();
}
function getSourceFile(filename: string): SourceFile {
return lookUp(sourceFilesByName, filename);
return lookUp(sourceFilesByName, getCanonicalFileName(filename));
}
function getFullTypeCheckChecker() {
@ -2190,7 +2166,7 @@ module ts {
var filename = oldSourceFiles[i].filename;
if (!hostCache.contains(filename) || changesInCompilationSettingsAffectSyntax) {
documentRegistry.releaseDocument(filename, oldSettings);
delete sourceFilesByName[filename];
delete sourceFilesByName[getCanonicalFileName(filename)];
}
}
}
@ -2233,7 +2209,7 @@ module ts {
}
// Remember the new sourceFile
sourceFilesByName[filename] = sourceFile;
sourceFilesByName[getCanonicalFileName(filename)] = sourceFile;
}
// Now create a new compiler
@ -2288,11 +2264,7 @@ module ts {
var allDiagnostics = checker.getDiagnostics(targetSourceFile);
if (compilerOptions.declaration) {
// If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
// Get emitter-diagnostics requires calling TypeChecker.emitFiles so we have to define CompilerHost.writer which does nothing because emitFiles function has side effects defined by CompilerHost.writer
var savedWriter = writer;
writer = (filename: string, data: string, writeByteOrderMark: boolean) => { };
allDiagnostics = allDiagnostics.concat(checker.invokeEmitter(targetSourceFile).diagnostics);
writer = savedWriter;
allDiagnostics = allDiagnostics.concat(checker.getDeclarationDiagnostics(targetSourceFile));
}
return allDiagnostics
}
@ -2800,8 +2772,11 @@ module ts {
if (isFirstDeclarationOfSymbolParameter(symbol)) {
return ScriptElementKind.parameterElement;
}
else if(symbol.valueDeclaration && symbol.valueDeclaration.flags & NodeFlags.Const) {
return ScriptElementKind.constantElement;
else if (symbol.valueDeclaration && isConst(symbol.valueDeclaration)) {
return ScriptElementKind.constElement;
}
else if (forEach(symbol.declarations, declaration => isLet(declaration))) {
return ScriptElementKind.letElement;
}
return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement;
}
@ -2858,7 +2833,11 @@ module ts {
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
case SyntaxKind.TypeAliasDeclaration: return ScriptElementKind.typeElement;
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
case SyntaxKind.VariableDeclaration: return node.flags & NodeFlags.Const ? ScriptElementKind.constantElement: ScriptElementKind.variableElement;
case SyntaxKind.VariableDeclaration: return isConst(node)
? ScriptElementKind.constElement
: node.flags & NodeFlags.Let
? ScriptElementKind.letElement
: ScriptElementKind.variableElement;
case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement;
case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement;
case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement;
@ -2957,7 +2936,7 @@ module ts {
switch (symbolKind) {
case ScriptElementKind.memberVariableElement:
case ScriptElementKind.variableElement:
case ScriptElementKind.constantElement:
case ScriptElementKind.constElement:
case ScriptElementKind.parameterElement:
case ScriptElementKind.localVariableElement:
// If it is call or construct signature of lambda's write type name
@ -3033,6 +3012,10 @@ module ts {
}
if (symbolFlags & SymbolFlags.Enum) {
addNewLineIfDisplayPartsExist();
if (forEach(symbol.declarations, declaration => isConstEnumDeclaration(declaration))) {
displayParts.push(keywordPart(SyntaxKind.ConstKeyword));
displayParts.push(spacePart());
}
displayParts.push(keywordPart(SyntaxKind.EnumKeyword));
displayParts.push(spacePart());
addFullSymbolName(symbol);
@ -3326,11 +3309,10 @@ module ts {
/// Triple slash reference comments
var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined);
if (comment) {
var targetFilename = isRootedDiskPath(comment.filename) ? comment.filename : combinePaths(getDirectoryPath(filename), comment.filename);
targetFilename = normalizePath(targetFilename);
if (program.getSourceFile(targetFilename)) {
var referenceFile = tryResolveScriptReference(program, sourceFile, comment);
if (referenceFile) {
return [{
fileName: targetFilename,
fileName: referenceFile.filename,
textSpan: TextSpan.fromBounds(0, 0),
kind: ScriptElementKind.scriptElement,
name: comment.filename,
@ -3991,39 +3973,56 @@ module ts {
var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations);
// Get the text to search for, we need to normalize it as external module names will have quote
var symbolName = getNormalizedSymbolName(symbol.name, declarations);
var declaredName = getDeclaredName(symbol);
// Get syntactic diagnostics
// Try to get the smallest valid scope that we can limit our search to;
// otherwise we'll need to search globally (i.e. include each file).
var scope = getSymbolScope(symbol);
if (scope) {
result = [];
getReferencesInNode(scope, symbol, symbolName, node, searchMeaning, findInStrings, findInComments, result);
getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
}
else {
var internedName = getInternedName(symbol, declarations)
forEach(sourceFiles, sourceFile => {
cancellationToken.throwIfCancellationRequested();
if (lookUp(sourceFile.identifiers, symbolName)) {
if (lookUp(sourceFile.identifiers, internedName)) {
result = result || [];
getReferencesInNode(sourceFile, symbol, symbolName, node, searchMeaning, findInStrings, findInComments, result);
getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
}
});
}
return result;
function getNormalizedSymbolName(symbolName: string, declarations: Declaration[]): string {
function getDeclaredName(symbol: Symbol) {
var name = typeInfoResolver.symbolToString(symbol);
return stripQuotes(name);
}
function getInternedName(symbol: Symbol, declarations: Declaration[]): string {
// Special case for function expressions, whose names are solely local to their bodies.
var functionExpression = forEach(declarations, d => d.kind === SyntaxKind.FunctionExpression ? <FunctionExpression>d : undefined);
// When a name gets interned into a SourceFile's 'identifiers' Map,
// its name is escaped and stored in the same way its symbol name/identifier
// name should be stored. Function expressions, however, are a special case,
// because despite sometimes having a name, the binder unconditionally binds them
// to a symbol with the name "__function".
if (functionExpression && functionExpression.name) {
var name = functionExpression.name.text;
}
else {
var name = symbolName;
var name = symbol.name;
}
return stripQuotes(name);
}
function stripQuotes(name: string) {
var length = name.length;
if (length >= 2 && name.charCodeAt(0) === CharacterCodes.doubleQuote && name.charCodeAt(length - 1) === CharacterCodes.doubleQuote) {
return name.substring(1, length - 1);
@ -4729,7 +4728,7 @@ module ts {
// Perform semantic and force a type check before emit to ensure that all symbols are updated
// EmitFiles will report if there is an error from TypeChecker and Emitter
// Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file
var emitFilesResult = getFullTypeCheckChecker().invokeEmitter(targetSourceFile);
var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile);
emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus;
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput
@ -4863,68 +4862,6 @@ module ts {
return SignatureHelp.getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken);
}
function getSignatureAtPosition(filename: string, position: number): SignatureInfo {
var signatureHelpItems = getSignatureHelpItems(filename, position);
if (!signatureHelpItems) {
return undefined;
}
var currentArgumentState = { argumentIndex: signatureHelpItems.argumentIndex, argumentCount: signatureHelpItems.argumentCount };
var formalSignatures: FormalSignatureItemInfo[] = [];
forEach(signatureHelpItems.items, signature => {
var signatureInfoString = displayPartsToString(signature.prefixDisplayParts);
var parameters: FormalParameterInfo[] = [];
if (signature.parameters) {
for (var i = 0, n = signature.parameters.length; i < n; i++) {
var parameter = signature.parameters[i];
// add the parameter to the string
if (i) {
signatureInfoString += displayPartsToString(signature.separatorDisplayParts);
}
var start = signatureInfoString.length;
signatureInfoString += displayPartsToString(parameter.displayParts);
var end = signatureInfoString.length;
// add the parameter to the list
parameters.push({
name: parameter.name,
isVariable: i === n - 1 && signature.isVariadic,
docComment: displayPartsToString(parameter.documentation),
minChar: start,
limChar: end
});
}
}
signatureInfoString += displayPartsToString(signature.suffixDisplayParts);
formalSignatures.push({
signatureInfo: signatureInfoString,
docComment: displayPartsToString(signature.documentation),
parameters: parameters,
typeParameters: [],
});
});
var actualSignature: ActualSignatureInfo = {
parameterMinChar: signatureHelpItems.applicableSpan.start(),
parameterLimChar: signatureHelpItems.applicableSpan.end(),
currentParameterIsTypeParameter: false,
currentParameter: currentArgumentState.argumentIndex
};
return {
actual: actualSignature,
formal: formalSignatures,
activeFormal: 0
};
}
/// Syntactic features
function getCurrentSourceFile(filename: string): SourceFile {
filename = normalizeSlashes(filename);
@ -5551,7 +5488,7 @@ module ts {
getFormattingEditsForDocument,
getFormattingEditsAfterKeystroke,
getEmitOutput,
getSignatureAtPosition,
getSourceFile: getCurrentSourceFile,
};
}
@ -5611,7 +5548,8 @@ module ts {
return true;
}
function getClassificationsForLine(text: string, lexState: EndOfLineState): ClassificationResult {
// 'classifyKeywordsInGenerics' should be 'true' when a syntactic classifier is not present.
function getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): ClassificationResult {
var offset = 0;
var token = SyntaxKind.Unknown;
var lastNonTriviaToken = SyntaxKind.Unknown;
@ -5698,7 +5636,7 @@ module ts {
token === SyntaxKind.StringKeyword ||
token === SyntaxKind.NumberKeyword ||
token === SyntaxKind.BooleanKeyword) {
if (angleBracketStack > 0) {
if (angleBracketStack > 0 && !classifyKeywordsInGenerics) {
// If it looks like we're could be in something generic, don't classify this
// as a keyword. We may just get overwritten by the syntactic classifier,
// causing a noisy experience for the user.

View File

@ -98,9 +98,6 @@ module ts {
getSignatureHelpItems(fileName: string, position: number): string;
// Obsolete. Use getSignatureHelpItems instead.
getSignatureAtPosition(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
* { canRename: boolean, localizedErrorMessage: string, displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: { start; length } }
@ -164,7 +161,7 @@ module ts {
}
export interface ClassifierShim extends Shim {
getClassificationsForLine(text: string, lexState: EndOfLineState): string;
getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): string;
}
export interface CoreServicesShim extends Shim {
@ -609,14 +606,6 @@ module ts {
});
}
public getSignatureAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getSignatureAtPosition('" + fileName + "', " + position + ")",
() => {
return this.languageService.getSignatureAtPosition(fileName, position);
});
}
/// GOTO DEFINITION
/**
@ -805,8 +794,8 @@ module ts {
}
/// COLORIZATION
public getClassificationsForLine(text: string, lexState: EndOfLineState): string {
var classification = this.classifier.getClassificationsForLine(text, lexState);
public getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): string {
var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
var items = classification.entries;
var result = "";
for (var i = 0; i < items.length; i++) {

View File

@ -164,6 +164,20 @@ module ts.SignatureHelp {
//}
var emptyArray: any[] = [];
const enum ArgumentListKind {
TypeArguments,
CallArguments,
TaggedTemplateArguments
}
interface ArgumentListInfo {
kind: ArgumentListKind;
invocation: CallLikeExpression;
argumentsSpan: TextSpan;
argumentIndex?: number;
argumentCount: number;
}
export function getSignatureHelpItems(sourceFile: SourceFile, position: number, typeInfoResolver: TypeChecker, cancellationToken: CancellationTokenObject): SignatureHelpItems {
// Decide whether to show signature help
var startingToken = findTokenOnLeftOfPosition(sourceFile, position);
@ -180,7 +194,7 @@ module ts.SignatureHelp {
return undefined;
}
var call = <CallExpression>argumentInfo.list.parent;
var call = argumentInfo.invocation;
var candidates = <Signature[]>[];
var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates);
cancellationToken.throwIfCancellationRequested();
@ -192,50 +206,195 @@ module ts.SignatureHelp {
return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo);
/**
* If node is an argument, returns its index in the argument list.
* If not, returns -1.
* Returns relevant information for the argument list and the current argument if we are
* in the argument of an invocation; returns undefined otherwise.
*/
function getImmediatelyContainingArgumentInfo(node: Node): ListItemInfo {
if (node.parent.kind !== SyntaxKind.CallExpression && node.parent.kind !== SyntaxKind.NewExpression) {
return undefined;
}
function getImmediatelyContainingArgumentInfo(node: Node): ArgumentListInfo {
if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) {
var callExpression = <CallExpression>node.parent;
// There are 3 cases to handle:
// 1. The token introduces a list, and should begin a sig help session
// 2. The token is either not associated with a list, or ends a list, so the session should end
// 3. The token is buried inside a list, and should give sig help
//
// The following are examples of each:
//
// Case 1:
// foo<#T, U>(#a, b) -> The token introduces a list, and should begin a sig help session
// Case 2:
// fo#o<T, U>#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end
// Case 3:
// foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give sig help
// Find out if 'node' is an argument, a type argument, or neither
if (node.kind === SyntaxKind.LessThanToken ||
node.kind === SyntaxKind.OpenParenToken) {
// Find the list that starts right *after* the < or ( token.
// If the user has just opened a list, consider this item 0.
var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile);
var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
Debug.assert(list !== undefined);
return {
kind: isTypeArgList ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments,
invocation: callExpression,
argumentsSpan: getApplicableSpanForArguments(list),
argumentIndex: 0,
argumentCount: getCommaBasedArgCount(list)
};
}
// There are 3 cases to handle:
// 1. The token introduces a list, and should begin a sig help session
// 2. The token is either not associated with a list, or ends a list, so the session should end
// 3. The token is buried inside a list, and should give sig help
//
// The following are examples of each:
//
// Case 1:
// foo<$T, U>($a, b) -> The token introduces a list, and should begin a sig help session
// Case 2:
// fo$o<T, U>$(a, b)$ -> The token is either not associated with a list, or ends a list, so the session should end
// Case 3:
// foo<T$, U$>(a$, $b$) -> The token is buried inside a list, and should give sig help
var parent = <CallExpression>node.parent;
// Find out if 'node' is an argument, a type argument, or neither
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
// Find the list that starts right *after* the < or ( token.
// If the user has just opened a list, consider this item 0.
var list = getChildListThatStartsWithOpenerToken(parent, node, sourceFile);
Debug.assert(list !== undefined);
return {
list,
listItemIndex: 0
};
}
// findListItemInfo can return undefined if we are not in parent's argument list
// or type argument list. This includes cases where the cursor is:
// - To the right of the closing paren, non-substitution template, or template tail.
// - Between the type arguments and the arguments (greater than token)
// - On the target of the call (parent.func)
// - On the 'new' keyword in a 'new' expression
var listItemInfo = findListItemInfo(node);
if (listItemInfo) {
var list = listItemInfo.list;
var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
// findListItemInfo can return undefined if we are not in parent's argument list
// or type argument list. This includes cases where the cursor is:
// - To the right of the closing paren
// - Between the type arguments and the arguments (greater than token)
// - On the target of the call (parent.func)
// - On the 'new' keyword in a 'new' expression
return findListItemInfo(node);
// The listItemIndex we got back includes commas. Our goal is to return the index of the proper
// item (not including commas). Here are some examples:
// 1. foo(a, b, c #) -> the listItemIndex is 4, we want to return 2
// 2. foo(a, b, # c) -> listItemIndex is 3, we want to return 2
// 3. foo(#a) -> listItemIndex is 0, we want to return 0
//
// In general, we want to subtract the number of commas before the current index.
// But if we are on a comma, we also want to pretend we are on the argument *following*
// the comma. That amounts to taking the ceiling of half the index.
var argumentIndex = (listItemInfo.listItemIndex + 1) >> 1;
return {
kind: isTypeArgList ? ArgumentListKind.TypeArguments : ArgumentListKind.CallArguments,
invocation: callExpression,
argumentsSpan: getApplicableSpanForArguments(list),
argumentIndex: argumentIndex,
argumentCount: getCommaBasedArgCount(list)
};
}
}
else if (node.kind === SyntaxKind.NoSubstitutionTemplateLiteral && node.parent.kind === SyntaxKind.TaggedTemplateExpression) {
// Check if we're actually inside the template;
// otherwise we'll fall out and return undefined.
if (isInsideTemplateLiteral(<LiteralExpression>node, position)) {
return getArgumentListInfoForTemplate(<TaggedTemplateExpression>node.parent, /*argumentIndex*/ 0);
}
}
else if (node.kind === SyntaxKind.TemplateHead && node.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
var templateExpression = <TemplateExpression>node.parent;
var tagExpression = <TaggedTemplateExpression>templateExpression.parent;
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
var argumentIndex = isInsideTemplateLiteral(<LiteralExpression>node, position) ? 0 : 1;
return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
}
else if (node.parent.kind === SyntaxKind.TemplateSpan && node.parent.parent.parent.kind === SyntaxKind.TaggedTemplateExpression) {
var templateSpan = <TemplateSpan>node.parent;
var templateExpression = <TemplateExpression>templateSpan.parent;
var tagExpression = <TaggedTemplateExpression>templateExpression.parent;
Debug.assert(templateExpression.kind === SyntaxKind.TemplateExpression);
// If we're just after a template tail, don't show signature help.
if (node.kind === SyntaxKind.TemplateTail && position >= node.getEnd() && !isUnterminatedTemplateEnd(<LiteralExpression>node)) {
return undefined;
}
var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node);
return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
}
return undefined;
}
function getContainingArgumentInfo(node: Node): ListItemInfo {
function getCommaBasedArgCount(argumentsList: Node) {
// The number of arguments is the number of commas plus one, unless the list
// is completely empty, in which case there are 0 arguments.
return argumentsList.getChildCount() === 0
? 0
: 1 + countWhere(argumentsList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
}
// spanIndex is either the index for a given template span.
// This does not give appropriate results for a NoSubstitutionTemplateLiteral
function getArgumentIndexForTemplatePiece(spanIndex: number, node: Node): number {
// Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1.
// There are three cases we can encounter:
// 1. We are precisely in the template literal (argIndex = 0).
// 2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1).
// 3. We are directly to the right of the template literal, but because we look for the token on the left,
// not enough to put us in the substitution expression; we should consider ourselves part of
// the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1).
//
// Example: f `# abcd $#{# 1 + 1# }# efghi ${ #"#hello"# } # `
// ^ ^ ^ ^ ^ ^ ^ ^ ^
// Case: 1 1 3 2 1 3 2 2 1
Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
if (isTemplateLiteralKind(node.kind)) {
if (isInsideTemplateLiteral(<LiteralExpression>node, position)) {
return 0;
}
return spanIndex + 2;
}
return spanIndex + 1;
}
function getArgumentListInfoForTemplate(tagExpression: TaggedTemplateExpression, argumentIndex: number): ArgumentListInfo {
// argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument.
var argumentCount = tagExpression.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral
? 1
: (<TemplateExpression>tagExpression.template).templateSpans.length + 1;
return {
kind: ArgumentListKind.TaggedTemplateArguments,
invocation: tagExpression,
argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression),
argumentIndex: argumentIndex,
argumentCount: argumentCount
};
}
function getApplicableSpanForArguments(argumentsList: Node): TextSpan {
// We use full start and skip trivia on the end because we want to include trivia on
// both sides. For example,
//
// foo( /*comment */ a, b, c /*comment*/ )
// | |
//
// The applicable span is from the first bar to the second bar (inclusive,
// but not including parentheses)
var applicableSpanStart = argumentsList.getFullStart();
var applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
}
function getApplicableSpanForTaggedTemplate(taggedTemplate: TaggedTemplateExpression): TextSpan {
var template = taggedTemplate.template;
var applicableSpanStart = template.getStart();
var applicableSpanEnd = template.getEnd();
// We need to adjust the end position for the case where the template does not have a tail.
// Otherwise, we will not show signature help past the expression.
// For example,
//
// ` ${ 1 + 1 foo(10)
// | |
//
// This is because a Missing node has no width. However, what we actually want is to include trivia
// leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail.
if (template.kind === SyntaxKind.TemplateExpression) {
var lastSpan = lastOrUndefined((<TemplateExpression>template).templateSpans);
if (lastSpan.literal.kind === SyntaxKind.Missing) {
applicableSpanEnd = skipTrivia(sourceFile.text, applicableSpanEnd, /*stopAfterLineBreak*/ false);
}
}
return new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
}
function getContainingArgumentInfo(node: Node): ArgumentListInfo {
for (var n = node; n.kind !== SyntaxKind.SourceFile; n = n.parent) {
if (n.kind === SyntaxKind.FunctionBlock) {
return undefined;
@ -292,14 +451,13 @@ module ts.SignatureHelp {
return maxParamsSignatureIndex;
}
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);
function createSignatureHelpItems(candidates: Signature[], bestSignature: Signature, argumentListInfo: ArgumentListInfo): SignatureHelpItems {
var applicableSpan = argumentListInfo.argumentsSpan;
var isTypeParameterList = argumentListInfo.kind === ArgumentListKind.TypeArguments;
var callTargetNode = (<CallExpression>argumentListOrTypeArgumentList.parent).func;
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTargetNode);
var invocation = argumentListInfo.invocation;
var callTarget = getInvokedExpression(invocation)
var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTarget);
var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
var signatureHelpParameters: SignatureHelpParameter[];
@ -310,27 +468,28 @@ module ts.SignatureHelp {
prefixDisplayParts.push.apply(prefixDisplayParts, callTargetDisplayParts);
}
if (isTypeParameterHelp) {
if (isTypeParameterList) {
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
var typeParameters = candidateSignature.typeParameters;
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
var parameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, argumentListOrTypeArgumentList));
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation));
suffixDisplayParts.push.apply(suffixDisplayParts, parameterParts);
}
else {
var typeParameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, argumentListOrTypeArgumentList));
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation));
prefixDisplayParts.push.apply(prefixDisplayParts, typeParameterParts);
prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
var parameters = candidateSignature.parameters;
signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
}
var returnTypeParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, argumentListOrTypeArgumentList));
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation));
suffixDisplayParts.push.apply(suffixDisplayParts, returnTypeParts);
return {
@ -343,34 +502,10 @@ module ts.SignatureHelp {
};
});
// We use full start and skip trivia on the end because we want to include trivia on
// both sides. For example,
//
// foo( /*comment */ a, b, c /*comment*/ )
// | |
//
// The applicable span is from the first bar to the second bar (inclusive,
// but not including parentheses)
var applicableSpanStart = argumentListOrTypeArgumentList.getFullStart();
var applicableSpanEnd = skipTrivia(sourceFile.text, argumentListOrTypeArgumentList.end, /*stopAfterLineBreak*/ false);
var applicableSpan = new TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
var argumentIndex = argumentListInfo.argumentIndex;
// The listItemIndex we got back includes commas. Our goal is to return the index of the proper
// item (not including commas). Here are some examples:
// 1. foo(a, b, c $) -> the listItemIndex is 4, we want to return 2
// 2. foo(a, b, $ c) -> listItemIndex is 3, we want to return 2
// 3. foo($a) -> listItemIndex is 0, we want to return 0
//
// In general, we want to subtract the number of commas before the current index.
// But if we are on a comma, we also want to pretend we are on the argument *following*
// the comma. That amounts to taking the ceiling of half the index.
var argumentIndex = (argumentInfoOrTypeArgumentInfo.listItemIndex + 1) >> 1;
// argumentCount is the number of commas plus one, unless the list is completely empty,
// in which case there are 0.
var argumentCount = argumentListOrTypeArgumentList.getChildCount() === 0
? 0
: 1 + countWhere(argumentListOrTypeArgumentList.getChildren(), arg => arg.kind === SyntaxKind.CommaToken);
// argumentCount is the *apparent* number of arguments.
var argumentCount = argumentListInfo.argumentCount;
var selectedItemIndex = candidates.indexOf(bestSignature);
if (selectedItemIndex < 0) {
@ -387,7 +522,7 @@ module ts.SignatureHelp {
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
var displayParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, argumentListOrTypeArgumentList));
typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation));
var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark);
@ -401,7 +536,7 @@ module ts.SignatureHelp {
function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter {
var displayParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, argumentListOrTypeArgumentList));
typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation));
return {
name: typeParameter.symbol.name,

View File

@ -621,9 +621,10 @@ var TypeScript;
SyntaxKind[SyntaxKind["Parameter"] = 209] = "Parameter";
SyntaxKind[SyntaxKind["EnumElement"] = 210] = "EnumElement";
SyntaxKind[SyntaxKind["TypeAnnotation"] = 211] = "TypeAnnotation";
SyntaxKind[SyntaxKind["ComputedPropertyName"] = 212] = "ComputedPropertyName";
SyntaxKind[SyntaxKind["ExternalModuleReference"] = 213] = "ExternalModuleReference";
SyntaxKind[SyntaxKind["ModuleNameModuleReference"] = 214] = "ModuleNameModuleReference";
SyntaxKind[SyntaxKind["ExpressionBody"] = 212] = "ExpressionBody";
SyntaxKind[SyntaxKind["ComputedPropertyName"] = 213] = "ComputedPropertyName";
SyntaxKind[SyntaxKind["ExternalModuleReference"] = 214] = "ExternalModuleReference";
SyntaxKind[SyntaxKind["ModuleNameModuleReference"] = 215] = "ModuleNameModuleReference";
SyntaxKind[SyntaxKind["FirstStandardKeyword"] = SyntaxKind.BreakKeyword] = "FirstStandardKeyword";
SyntaxKind[SyntaxKind["LastStandardKeyword"] = SyntaxKind.WithKeyword] = "LastStandardKeyword";
SyntaxKind[SyntaxKind["FirstFutureReservedKeyword"] = SyntaxKind.ClassKeyword] = "FirstFutureReservedKeyword";
@ -1016,7 +1017,15 @@ var definitions = [
{ name: 'asterixToken', isToken: true, isOptional: true },
{ name: 'identifier', isToken: true },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
{
name: 'ExpressionBody',
baseType: 'ISyntaxNode',
children: [
{ name: 'equalsGreaterThanToken', isToken: true },
{ name: 'expression', type: 'IExpressionSyntax' }
]
},
{
@ -1246,6 +1255,7 @@ var definitions = [
baseType: 'ISyntaxNode',
interfaces: ['IStatementSyntax'],
children: [
{ name: 'equalsGreaterThanToken', isToken: true, isOptional: 'true' },
{ name: 'openBraceToken', isToken: true },
{ name: 'statements', isList: true, elementType: 'IStatementSyntax' },
{ name: 'closeBraceToken', isToken: true, excludeFromAST: true }
@ -1289,7 +1299,7 @@ var definitions = [
children: [
{ name: 'expression', type: 'ILeftHandSideExpressionSyntax' },
{ name: 'openBracketToken', isToken: true, excludeFromAST: true },
{ name: 'argumentExpression', type: 'IExpressionSyntax' },
{ name: 'argumentExpression', type: 'IExpressionSyntax', isOptional: true },
{ name: 'closeBracketToken', isToken: true, excludeFromAST: true }
]
},
@ -1488,7 +1498,7 @@ var definitions = [
{ name: 'modifiers', isList: true, elementType: 'ISyntaxToken' },
{ name: 'constructorKeyword', isToken: true },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -1501,7 +1511,7 @@ var definitions = [
{ name: 'asterixToken', isToken: true, isOptional: true },
{ name: 'propertyName', type: 'IPropertyNameSyntax' },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -1514,7 +1524,7 @@ var definitions = [
{ name: 'getKeyword', isToken: true, excludeFromAST: true },
{ name: 'propertyName', type: 'IPropertyNameSyntax' },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'block', type: 'BlockSyntax' }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
{
@ -1526,7 +1536,7 @@ var definitions = [
{ name: 'setKeyword', isToken: true, excludeFromAST: true },
{ name: 'propertyName', type: 'IPropertyNameSyntax' },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'block', type: 'BlockSyntax' }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -1558,7 +1568,7 @@ var definitions = [
interfaces: ['IStatementSyntax'],
children: [
{ name: 'throwKeyword', isToken: true, excludeFromAST: true },
{ name: 'expression', type: 'IExpressionSyntax' },
{ name: 'expression', type: 'IExpressionSyntax', isOptional: true },
{ name: 'semicolonToken', isToken: true, isOptional: true, excludeFromAST: true }
]
},
@ -1763,7 +1773,7 @@ var definitions = [
{ name: 'asterixToken', isToken: true, isOptional: true },
{ name: 'propertyName', type: 'IPropertyNameSyntax' },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'block', type: 'BlockSyntax' }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
{
@ -1775,7 +1785,7 @@ var definitions = [
{ name: 'asterixToken', isToken: true, isOptional: true },
{ name: 'identifier', isToken: true, isOptional: true },
{ name: 'callSignature', type: 'CallSignatureSyntax' },
{ name: 'block', type: 'BlockSyntax' }
{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
{

File diff suppressed because one or more lines are too long

View File

@ -1,29 +1,24 @@
///<reference path='references.ts' />
module TypeScript {
export const enum ParserContextFlags {
StrictMode = 1 << 0,
DisallowIn = 1 << 1,
Yield = 1 << 2,
GeneratorParameter = 1 << 3,
Mask = 0xF
}
export enum SyntaxNodeConstants {
None = 0,
// Masks that we use to place information about a node into a single int. The first bit tells
// us if we've computed the data for a node.
//
// The second bit tells us if the node is incrementally reusable if it does not
// containe any skipped tokens, zero width tokens, regex tokens in it ("/", "/=" or "/.../"),
// and contains no tokens that were parser generated.
//
// The next bit lets us know if the nodes was parsed in a strict context or node. A node can
// only be used by the incremental parser if it is parsed in the same strict context as before.
// last masks off the part of the int
//
// The first four bit of the flags are used to store parser context flags.
// The width of the node is stored in the remainder of the int. This allows us up to 128MB
// for a node by using all 27 bits. However, in the common case, we'll use less than 27 bits
// for the width. Thus, the info will be stored in a single int in chakra.
DataComputed = 0x00000001, // 0000 0000 0000 0000 0000 0000 0000 0001
IncrementallyUnusableMask = 0x00000002, // 0000 0000 0000 0000 0000 0000 0000 0010
ParsedInStrictModeContext = 0x00000004, // 0000 0000 0000 0000 0000 0000 0000 0100
ParsedInDisallowInContext = 0x00000008, // 0000 0000 0000 0000 0000 0000 0000 1000
ParsedInYieldContext = 0x00000010, // 0000 0000 0000 0000 0000 0000 0001 0000
ParsedInGeneratorParameterContext = 0x00000020, // 0000 0000 0000 0000 0000 0000 0010 0000
FullWidthShift = 1 << 6, // 1111 1111 1111 1111 1111 1111 1100 0000
DataComputed = 1 << 4, // 0000 0000 0000 0000 0000 0000 0001 0000
IncrementallyUnusableMask = 1 << 5, // 0000 0000 0000 0000 0000 0000 0010 0000
FullWidthShift = 1 << 6, // 1111 1111 1111 1111 1111 1111 1100 0000
}
}

View File

@ -4,8 +4,10 @@ module TypeScript.IncrementalParser {
interface IParserRewindPoint {
// Information used by the incremental parser source.
oldSourceUnitCursor: SyntaxCursor;
changeDelta: number;
changeRange: TextChangeRange;
}
interface ISyntaxElementInternal extends ISyntaxElement {
intersectsChange: boolean;
}
// Parser source used in incremental scenarios. This parser source wraps an old tree, text
@ -21,9 +23,6 @@ module TypeScript.IncrementalParser {
// prevent this level of reuse include substantially destructive operations like introducing
// "/*" without a "*/" nearby to terminate the comment.
function createParserSource(oldSyntaxTree: SyntaxTree, textChangeRange: TextChangeRange, text: ISimpleText): Parser.IParserSource {
var fileName = oldSyntaxTree.fileName();
var languageVersion = oldSyntaxTree.languageVersion();
// The underlying source that we will use to scan tokens from any new text, or any tokens
// from the old tree that we decide we can't use for any reason. We will also continue
// scanning tokens from this source until we've decided that we're resynchronized and can
@ -31,40 +30,15 @@ module TypeScript.IncrementalParser {
//
// This parser source also keeps track of the absolute position in the text that we're in,
// and any token diagnostics produced. That way we dont' have to track that ourselves.
var _scannerParserSource: Scanner.IScannerParserSource;
// The range of text in the *original* text that was changed, and the new length of it after
// the change.
var _changeRange: TextChangeRange;
// Cached value of _changeRange.newSpan(). Cached for performance.
var _changeRangeNewSpan: TextSpan;
// This number represents how our position in the old tree relates to the position we're
// pointing at in the new text. If it is 0 then our positions are in sync and we can read
// nodes or tokens from the old tree. If it is non-zero, then our positions are not in
// sync and we cannot use nodes or tokens from the old tree.
//
// Now, changeDelta could be negative or positive. Negative means 'the position we're at
// in the original tree is behind the position we're at in the text'. In this case we
// keep throwing out old nodes or tokens (and thus move forward in the original tree) until
// changeDelta becomes 0 again or positive. If it becomes 0 then we are resynched and can
// read nodes or tokesn from the tree.
//
// If changeDelta is positive, that means the current node or token we're pointing at in
// the old tree is at a further ahead position than the position we're pointing at in the
// new text. In this case we have no choice but to scan tokens from teh new text. We will
// continue to do so until, again, changeDelta becomes 0 and we've resynced, or change delta
// becomes negative and we need to skip nodes or tokes in the original tree.
var _changeDelta: number = 0;
var _scannerParserSource = Scanner.createParserSource(oldSyntaxTree.fileName(), text, oldSyntaxTree.languageVersion());
// The cursor we use to navigate through and retrieve nodes and tokens from the old tree.
var _oldSourceUnitCursor = getSyntaxCursor();
var oldSourceUnit = oldSyntaxTree.sourceUnit();
var _outstandingRewindPointCount = 0;
// Start the cursor pointing at the first element in the source unit (if it exists).
var _oldSourceUnitCursor = getSyntaxCursor();
if (oldSourceUnit.moduleElements.length > 0) {
_oldSourceUnitCursor.pushElement(childAt(oldSourceUnit.moduleElements, 0), /*indexInParent:*/ 0);
}
@ -74,8 +48,10 @@ module TypeScript.IncrementalParser {
// time this could be problematic would be if the user made a ton of discontinuous edits.
// For example, doing a column select on a *large* section of a code. If this is a
// problem, we can always update this code to handle multiple changes.
_changeRange = extendToAffectedRange(textChangeRange, oldSourceUnit);
_changeRangeNewSpan = _changeRange.newSpan();
var _changeRange = extendToAffectedRange(textChangeRange, oldSourceUnit);
// Cached value of _changeRange.newSpan(). Cached for performance.
var _changeRangeNewSpan = _changeRange.newSpan();
// The old tree's length, plus whatever length change was caused by the edit
// Had better equal the new text's length!
@ -83,8 +59,23 @@ module TypeScript.IncrementalParser {
Debug.assert((fullWidth(oldSourceUnit) - _changeRange.span().length() + _changeRange.newLength()) === text.length());
}
// Set up a scanner so that we can scan tokens out of the new text.
_scannerParserSource = Scanner.createParserSource(oldSyntaxTree.fileName(), text, oldSyntaxTree.languageVersion());
var delta = _changeRange.newSpan().length() - _changeRange.span().length();
// If we added or removed characters during the edit, then we need to go and adjust all
// the nodes after the edit. Those nodes may move forward down (if we inserted chars)
// or they may move backward (if we deleted chars).
//
// Doing this helps us out in two ways. First, it means that any nodes/tokens we want
// to reuse are already at the appropriate position in the new text. That way when we
// reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
// it very easy to determine if we can reuse a node. If the node's position is at where
// we are in the text, then we can reuse it. Otherwise we can't. If hte node's position
// is ahead of us, then we'll need to rescan tokens. If the node's position is behind
// us, then we'll need to skip it or crumble it as appropriate
//
// Also, mark any syntax elements that intersect the changed span. We know, up front,
// that we cannot reuse these elements.
updateTokenPositionsAndMarkElements(<ISyntaxElementInternal><ISyntaxElement>oldSourceUnit,
_changeRange.span().start(), _changeRange.span().end(), delta, /*fullStart:*/ 0);
function release() {
_scannerParserSource.release();
@ -93,8 +84,7 @@ module TypeScript.IncrementalParser {
_outstandingRewindPointCount = 0;
}
function extendToAffectedRange(changeRange: TextChangeRange,
sourceUnit: SourceUnitSyntax): TextChangeRange {
function extendToAffectedRange(changeRange: TextChangeRange, sourceUnit: SourceUnitSyntax): TextChangeRange {
// Consider the following code:
// void foo() { /; }
//
@ -105,14 +95,6 @@ module TypeScript.IncrementalParser {
// (as it does not intersect the actual original change range). Because an edit may
// change the token touching it, we actually need to look back *at least* one token so
// that the prior token sees that change.
//
// Note: i believe (outside of regex tokens) max lookahead is just one token for
// TypeScript. However, if this turns out to be wrong, we may have to increase how much
// futher we look back.
//
// Note: lookahead handling for regex characters is handled specially in during
// incremental parsing, and does not need to be handled here.
var maxLookahead = 1;
var start = changeRange.span().start();
@ -122,10 +104,6 @@ module TypeScript.IncrementalParser {
// start of the tree.
for (var i = 0; start > 0 && i <= maxLookahead; i++) {
var token = findToken(sourceUnit, start);
// Debug.assert(token.kind !== SyntaxKind.None);
// Debug.assert(token.kind() === SyntaxKind.EndOfFileToken || token.fullWidth() > 0);
var position = token.fullStart();
start = Math.max(0, position - 1);
@ -149,17 +127,8 @@ module TypeScript.IncrementalParser {
// Get a rewind point for our new text reader and for our old source unit cursor.
var rewindPoint = <IParserRewindPoint>_scannerParserSource.getRewindPoint();
// Clone our cursor. That way we can restore to that point if hte parser needs to rewind.
var oldSourceUnitCursorClone = cloneSyntaxCursor(_oldSourceUnitCursor);
// Store where we were when the rewind point was created.
rewindPoint.changeDelta = _changeDelta;
rewindPoint.changeRange = _changeRange;
rewindPoint.oldSourceUnitCursor = _oldSourceUnitCursor;
_oldSourceUnitCursor = oldSourceUnitCursorClone;
// Debug.assert(rewindPoint.pinCount === _oldSourceUnitCursor.pinCount());
// Clone our cursor. That way we can restore to that point if the parser needs to rewind.
rewindPoint.oldSourceUnitCursor = cloneSyntaxCursor(_oldSourceUnitCursor);
_outstandingRewindPointCount++;
return rewindPoint;
@ -167,15 +136,13 @@ module TypeScript.IncrementalParser {
function rewind(rewindPoint: IParserRewindPoint): void {
// Restore our state to the values when the rewind point was created.
_changeRange = rewindPoint.changeRange;
_changeDelta = rewindPoint.changeDelta;
// Reset the cursor to what it was when we got the rewind point. Make sure to return
// our existing cursor to the pool so it can be reused.
returnSyntaxCursor(_oldSourceUnitCursor);
_oldSourceUnitCursor = rewindPoint.oldSourceUnitCursor;
// Null out the cursor that the rewind point points to. This way we don't try
// Clear the cursor that the rewind point points to. This way we don't try
// to return it in 'releaseRewindPoint'.
rewindPoint.oldSourceUnitCursor = undefined;
@ -196,7 +163,7 @@ module TypeScript.IncrementalParser {
return _outstandingRewindPointCount > 0;
}
function canReadFromOldSourceUnit() {
function trySynchronizeCursorToPosition() {
// If we're currently pinned, then do not want to touch the cursor. Here's why. First,
// recall that we're 'pinned' when we're speculatively parsing. So say we were to allow
// returning old nodes/tokens while speculatively parsing. Then, the parser might start
@ -218,81 +185,72 @@ module TypeScript.IncrementalParser {
return false;
}
// If our current absolute position is in the middle of the changed range in the new text
// then we definitely can't read from the old source unit right now.
if (_changeRange && _changeRangeNewSpan.intersectsWithPosition(absolutePosition())) {
return false;
}
var absolutePos = absolutePosition();
while (true) {
if (_oldSourceUnitCursor.isFinished()) {
// Can't synchronize the cursor to the current position if the cursor is finished.
return false;
}
// First, try to sync up with the new text if we're behind.
syncCursorToNewTextIfBehind();
// Start with the current node or token the cursor is pointing at.
var currentNodeOrToken = _oldSourceUnitCursor.currentNodeOrToken();
// Now, if we're synced up *and* we're not currently pinned in the new text scanner,
// then we can read a node from the cursor. If we're pinned in the scanner then we
// can't read a node from the cursor because we will mess up the pinned scanner when
// we try to move it forward past this node.
return _changeDelta === 0 &&
!_oldSourceUnitCursor.isFinished();
}
// Node, move the cursor past any nodes or tokens that intersect the change range
// 1) they are never reusable.
// 2) their positions are wacky as they refer to the original text.
//
// We consider these nodes and tokens essentially invisible to all further parts
// of the incremental algorithm.
if ((<ISyntaxElementInternal><ISyntaxElement>currentNodeOrToken).intersectsChange) {
if (isNode(currentNodeOrToken)) {
_oldSourceUnitCursor.moveToFirstChild();
}
else {
_oldSourceUnitCursor.moveToNextSibling();
}
continue;
}
function updateTokenPosition(token: ISyntaxToken): void {
// If we got a node or token, and we're past the range of edited text, then walk its
// constituent tokens, making sure all their positions are correct. We don't need to
// do this for the tokens before the edited range (since their positions couldn't have
// been affected by the edit), and we don't need to do this for the tokens in the
// edited range, as their positions will be correct when the underlying parser source
// creates them.
var currentNodeOrTokenFullStart = fullStart(currentNodeOrToken);
if (currentNodeOrTokenFullStart === absolutePos) {
// We were able to synchronize the cursor to the current position. We can
// read from the cursor
return true;
}
if (isPastChangeRange()) {
token.setFullStart(absolutePosition());
}
}
if (currentNodeOrTokenFullStart > absolutePos) {
// The node or token is ahead of the current position. We'll need to rescan
// tokens until we catch up.
return false;
}
function updateNodePosition(node: ISyntaxNode): void {
// If we got a node or token, and we're past the range of edited text, then walk its
// constituent tokens, making sure all their positions are correct. We don't need to
// do this for the tokens before the edited range (since their positions couldn't have
// been affected by the edit), and we don't need to do this for the tokens in the
// edited range, as their positions will be correct when the underlying parser source
// creates them.
// The node or is behind the current position we're at in the text.
if (isPastChangeRange()) {
var position = absolutePosition();
var currentNodeOrTokenFullWidth = fullWidth(currentNodeOrToken);
var currentNodeOrTokenFullEnd = currentNodeOrTokenFullStart + currentNodeOrTokenFullWidth;
var tokens = getTokens(node);
for (var i = 0, n = tokens.length; i < n; i++) {
var token = tokens[i];
token.setFullStart(position);
position += token.fullWidth();
// If we're pointing at a node, and that node ends before our current position, we
// can just skip the node entirely. Or, if we're pointing at a token, we won't be
// able to break up that token any further and we should just move to the next
// token.
if (currentNodeOrTokenFullEnd <= absolutePos || isToken(currentNodeOrToken)) {
_oldSourceUnitCursor.moveToNextSibling();
}
else {
// We have a node, and it started before our absolute pos, and ended after our
// pos. Try to crumble this node to see if we'll be able to skip the first node
// or token contained within.
_oldSourceUnitCursor.moveToFirstChild();
}
}
}
function getTokens(node: ISyntaxNode): ISyntaxToken[] {
var tokens = node.__cachedTokens;
if (!tokens) {
tokens = [];
tokenCollectorWalker.tokens = tokens;
visitNodeOrToken(tokenCollectorWalker, node);
node.__cachedTokens = tokens;
tokenCollectorWalker.tokens = undefined;
}
return tokens;
}
function currentNode(): ISyntaxNode {
if (canReadFromOldSourceUnit()) {
if (trySynchronizeCursorToPosition()) {
// Try to read a node. If we can't then our caller will call back in and just try
// to get a token.
var node = tryGetNodeFromOldSourceUnit();
if (node) {
// Make sure the positions for the tokens in this node are correct.
updateNodePosition(node);
return node;
}
}
@ -302,11 +260,9 @@ module TypeScript.IncrementalParser {
}
function currentToken(): ISyntaxToken {
if (canReadFromOldSourceUnit()) {
if (trySynchronizeCursorToPosition()) {
var token = tryGetTokenFromOldSourceUnit();
if (token) {
// Make sure the token's position/text is correct.
updateTokenPosition(token);
return token;
}
}
@ -321,69 +277,13 @@ module TypeScript.IncrementalParser {
return _scannerParserSource.currentContextualToken();
}
function syncCursorToNewTextIfBehind() {
while (true) {
if (_oldSourceUnitCursor.isFinished()) {
// Can't sync up if the cursor is finished.
break;
}
if (_changeDelta >= 0) {
// Nothing to do if we're synced up or ahead of the text.
break;
}
// We're behind in the original tree. Throw out a node or token in an attempt to
// catch up to the position we're at in the new text.
var currentNodeOrToken = _oldSourceUnitCursor.currentNodeOrToken();
// If we're pointing at a node, and that node's width is less than our delta,
// then we can just skip that node. Otherwise, if we're pointing at a node
// whose width is greater than the delta, then crumble it and try again.
// Otherwise, we must be pointing at a token. Just skip it and try again.
if (isNode(currentNodeOrToken) && (fullWidth(currentNodeOrToken) > Math.abs(_changeDelta))) {
// We were pointing at a node whose width was more than changeDelta. Crumble the
// node and try again. Note: we haven't changed changeDelta. So the callers loop
// will just repeat this until we get to a node or token that we can skip over.
_oldSourceUnitCursor.moveToFirstChild();
}
else {
_oldSourceUnitCursor.moveToNextSibling();
// Get our change delta closer to 0 as we skip past this item.
_changeDelta += fullWidth(currentNodeOrToken);
// If this was a node, then our changeDelta is 0 or negative. If this was a
// token, then we could still be negative (and we have to read another token),
// we could be zero (we're done), or we could be positive (we've moved ahead
// of the new text). Only if we're negative will we continue looping.
}
}
// At this point, we must be either:
// a) done with the cursor
// b) (ideally) caught up to the new text position.
// c) ahead of the new text position.
// In case 'b' we can try to reuse a node from teh old tree.
// Debug.assert(_oldSourceUnitCursor.isFinished() || _changeDelta >= 0);
}
function intersectsWithChangeRangeSpanInOriginalText(start: number, length: number) {
return !isPastChangeRange() && _changeRange.span().intersectsWith(start, length);
}
function tryGetNodeFromOldSourceUnit(): ISyntaxNode {
// Debug.assert(canReadFromOldSourceUnit());
// Keep moving the cursor down to the first node that is safe to return. A node is
// safe to return if:
// a) it does not intersect the changed text.
// b) it does not contain skipped text.
// c) it does not have any zero width tokens in it.
// d) it does not have a regex token in it.
// e) we are still in the same strict or non-strict state that the node was originally parsed in.
// a) it does not contain skipped text.
// b) it does not have any zero width tokens in it.
// c) it does not have a regex token in it.
// d) we are still in the same strict or non-strict state that the node was originally parsed in.
while (true) {
var node = _oldSourceUnitCursor.currentNode();
if (node === undefined) {
@ -391,15 +291,10 @@ module TypeScript.IncrementalParser {
return undefined;
}
if (!intersectsWithChangeRangeSpanInOriginalText(absolutePosition(), fullWidth(node))) {
// Didn't intersect with the change range.
var isIncrementallyUnusuable = TypeScript.isIncrementallyUnusable(node);
if (!isIncrementallyUnusuable) {
// Didn't contain anything that would make it unusable. Awesome. This is
// a node we can reuse.
return node;
}
if (!TypeScript.isIncrementallyUnusable(node)) {
// Didn't contain anything that would make it unusable. Awesome. This is
// a node we can reuse.
return node;
}
// We couldn't use currentNode. Try to move to its first child (in case that's a
@ -409,9 +304,9 @@ module TypeScript.IncrementalParser {
}
}
function canReuseTokenFromOldSourceUnit(position: number, token: ISyntaxToken): boolean {
function canReuseTokenFromOldSourceUnit(token: ISyntaxToken): boolean {
// A token is safe to return if:
// a) it does not intersect the changed text.
// a) it did not intersect the change range.
// b) it does not contain skipped text.
// c) it is not zero width.
// d) it is not a contextual parser token.
@ -427,33 +322,21 @@ module TypeScript.IncrementalParser {
// need to make sure that if that the parser asks for a *token* we don't return it.
// Converted identifiers can't ever be created by the scanner, and as such, should not
// be returned by this source.
if (token) {
if (!intersectsWithChangeRangeSpanInOriginalText(position, token.fullWidth())) {
// Didn't intersect with the change range.
if (!token.isIncrementallyUnusable() && !Scanner.isContextualToken(token)) {
// Didn't contain anything that would make it unusable. Awesome. This is
// a token we can reuse.
return true;
}
}
}
return false;
return token &&
!(<ISyntaxElementInternal><ISyntaxElement>token).intersectsChange &&
!token.isIncrementallyUnusable() &&
!Scanner.isContextualToken(token);
}
function tryGetTokenFromOldSourceUnit(): ISyntaxToken {
// Debug.assert(canReadFromOldSourceUnit());
// get the current token that the cursor is pointing at.
var token = _oldSourceUnitCursor.currentToken();
return canReuseTokenFromOldSourceUnit(absolutePosition(), token)
? token : undefined;
return canReuseTokenFromOldSourceUnit(token) ? token : undefined;
}
function peekToken(n: number): ISyntaxToken {
if (canReadFromOldSourceUnit()) {
if (trySynchronizeCursorToPosition()) {
var token = tryPeekTokenFromOldSourceUnit(n);
if (token) {
return token;
@ -465,8 +348,6 @@ module TypeScript.IncrementalParser {
}
function tryPeekTokenFromOldSourceUnit(n: number): ISyntaxToken {
// Debug.assert(canReadFromOldSourceUnit());
// clone the existing cursor so we can move it forward and then restore ourselves back
// to where we started from.
@ -481,11 +362,6 @@ module TypeScript.IncrementalParser {
}
function tryPeekTokenFromOldSourceUnitWorker(n: number): ISyntaxToken {
// In order to peek the 'nth' token we need all the tokens up to that point. That way
// we know we know position that the nth token is at. The position is necessary so
// that we can test if this token (or any that precede it cross the change range).
var currentPosition = absolutePosition();
// First, make sure the cursor is pointing at a token.
_oldSourceUnitCursor.moveToFirstToken();
@ -493,111 +369,31 @@ module TypeScript.IncrementalParser {
for (var i = 0; i < n; i++) {
var interimToken = _oldSourceUnitCursor.currentToken();
if (!canReuseTokenFromOldSourceUnit(currentPosition, interimToken)) {
if (!canReuseTokenFromOldSourceUnit(interimToken)) {
return undefined;
}
currentPosition += interimToken.fullWidth();
_oldSourceUnitCursor.moveToNextSibling();
}
var token = _oldSourceUnitCursor.currentToken();
return canReuseTokenFromOldSourceUnit(currentPosition, token)
? token : undefined;
return canReuseTokenFromOldSourceUnit(token) ? token : undefined;
}
function consumeNode(node: ISyntaxNode): void {
// A node could have only come from the old source unit cursor. Update it and our
// current state.
// Debug.assert(_changeDelta === 0);
// Debug.assert(currentNode() === node);
_oldSourceUnitCursor.moveToNextSibling();
// Update the underlying source with where it should now be currently pointin.
var _absolutePosition = absolutePosition() + fullWidth(node);
_scannerParserSource.resetToPosition(_absolutePosition);
// Debug.assert(previousToken !== undefined);
// Debug.assert(previousToken.width() > 0);
//if (!isPastChangeRange()) {
// // If we still have a change range, then this node must have ended before the
// // change range starts. Thus, we don't need to call 'skipPastChanges'.
// Debug.assert(absolutePosition() < _changeRange.span().start());
//}
}
function consumeToken(currentToken: ISyntaxToken): void {
// Debug.assert(currentToken.fullWidth() > 0 || currentToken.kind === SyntaxKind.EndOfFileToken);
// This token may have come from the old source unit, or from the new text. Handle
// both accordingly.
if (_oldSourceUnitCursor.currentToken() === currentToken) {
// The token came from the old source unit. So our tree and text must be in sync.
// Debug.assert(_changeDelta === 0);
// Move the cursor past this token.
_oldSourceUnitCursor.moveToNextSibling();
// Debug.assert(!_normalParserSource.isPinned());
// Update the underlying source with where it should now be currently pointing. We
// don't need to do this when the token came from the new text as the source will
// automatically be placed in the right position.
var _absolutePosition = absolutePosition() + currentToken.fullWidth();
_scannerParserSource.resetToPosition(_absolutePosition);
// Debug.assert(previousToken !== undefined);
// Debug.assert(previousToken.width() > 0);
//if (!isPastChangeRange()) {
// // If we still have a change range, then this token must have ended before the
// // change range starts. Thus, we don't need to call 'skipPastChanges'.
// Debug.assert(absolutePosition() < _changeRange.span().start());
//}
}
else {
// the token came from the new text. That means the normal source moved forward,
// while the syntax cursor stayed in the same place. Thus our delta moves even
// further back.
_changeDelta -= currentToken.fullWidth();
// Move our underlying source forward.
_scannerParserSource.consumeToken(currentToken);
// Because we read a token from the new text, we may have moved ourselves past the
// change range. If we did, then we may also have to update our change delta to
// compensate for the length change between the old and new text.
if (!isPastChangeRange()) {
// var changeEndInNewText = _changeRange.span().start() + _changeRange.newLength();
if (absolutePosition() >= _changeRangeNewSpan.end()) {
_changeDelta += _changeRange.newLength() - _changeRange.span().length();
// Once we're past the change range, we no longer need it. Null it out.
// From now on we can check if we're past the change range just by seeing
// if this is undefined.
_changeRange = undefined;
}
}
}
}
function isPastChangeRange(): boolean {
return _changeRange === undefined;
function consumeNodeOrToken(nodeOrToken: ISyntaxNodeOrToken): void {
_scannerParserSource.consumeNodeOrToken(nodeOrToken);
}
return {
text: text,
fileName: fileName,
languageVersion: languageVersion,
fileName: oldSyntaxTree.fileName(),
languageVersion: oldSyntaxTree.languageVersion(),
absolutePosition: absolutePosition,
currentNode: currentNode,
currentToken: currentToken,
currentContextualToken: currentContextualToken,
peekToken: peekToken,
consumeNode: consumeNode,
consumeToken: consumeToken,
consumeNodeOrToken: consumeNodeOrToken,
getRewindPoint: getRewindPoint,
rewind: rewind,
releaseRewindPoint: releaseRewindPoint,
@ -699,7 +495,6 @@ module TypeScript.IncrementalParser {
// Makes this cursor into a deep copy of the cursor passed in.
function deepCopyFrom(other: SyntaxCursor): void {
// Debug.assert(currentPieceIndex === -1);
for (var i = 0, n = other.pieces.length; i < n; i++) {
var piece = other.pieces[i];
@ -709,8 +504,6 @@ module TypeScript.IncrementalParser {
pushElement(piece.element, piece.indexInParent);
}
// Debug.assert(currentPieceIndex === other.currentPieceIndex);
}
function isFinished(): boolean {
@ -725,9 +518,6 @@ module TypeScript.IncrementalParser {
var result = pieces[currentPieceIndex].element;
// The current element must always be a node or a token.
// Debug.assert(result !== undefined);
// Debug.assert(result.isNode() || result.isToken());
return <ISyntaxNodeOrToken>result;
}
@ -751,9 +541,6 @@ module TypeScript.IncrementalParser {
return;
}
// The last element must be a token or a node.
// Debug.assert(isNode(nodeOrToken));
// Either the node has some existent child, then move to it. if it doesn't, then it's
// an empty node. Conceptually the first child of an empty node is really just the
// next sibling of the empty node.
@ -772,8 +559,6 @@ module TypeScript.IncrementalParser {
// This element must have been an empty node. Moving to its 'first child' is equivalent to just
// moving to the next sibling.
// Debug.assert(fullWidth(nodeOrToken) === 0);
moveToNextSibling();
}
@ -817,15 +602,11 @@ module TypeScript.IncrementalParser {
if (isList(element)) {
// We cannot ever get an empty list in our piece path. Empty lists are 'shared' and
// we make sure to filter that out before pushing any children.
// Debug.assert(childCount(element) > 0);
pushElement(childAt(element, 0), /*indexInParent:*/ 0);
}
}
function pushElement(element: ISyntaxElement, indexInParent: number): void {
// Debug.assert(element !== undefined);
// Debug.assert(indexInParent >= 0);
currentPieceIndex++;
// Reuse an existing piece if we have one. Otherwise, push a new piece to our list.
@ -847,7 +628,6 @@ module TypeScript.IncrementalParser {
continue;
}
// Debug.assert(isToken(element));
return;
}
}
@ -856,7 +636,6 @@ module TypeScript.IncrementalParser {
moveToFirstToken();
var element = currentNodeOrToken();
// Debug.assert(element === undefined || element.isToken());
return <ISyntaxToken>element;
}
@ -887,6 +666,94 @@ module TypeScript.IncrementalParser {
}
var tokenCollectorWalker = new TokenCollectorWalker();
function updateTokenPositionsAndMarkElements(element: ISyntaxElement, changeStart: number, changeRangeOldEnd: number, delta: number, fullStart: number): void {
// First, try to skip past any elements that we dont' need to move. We don't need to
// move any elements that don't start after the end of the change range.
if (fullStart > changeRangeOldEnd) {
// Note, we only move elements that are truly after the end of the change range.
// We consider elements that are touching the end of the change range to be unusable.
forceUpdateTokenPositionsForElement(element, delta);
}
else {
// Check if the element intersects the change range. If it does, then it is not
// reusable. Also, we'll need to recurse to see what constituent portions we may
// be able to use.
var fullEnd = fullStart + fullWidth(element);
if (fullEnd >= changeStart) {
(<ISyntaxElementInternal>element).intersectsChange = true;
if (isList(element)) {
var list = <ISyntaxNodeOrToken[]>element;
for (var i = 0, n = list.length; i < n; i++) {
var child: ISyntaxElement = list[i];
updateTokenPositionsAndMarkElements(child, changeStart, changeRangeOldEnd, delta, fullStart);
fullStart += fullWidth(child);
}
}
else if (isNode(element)) {
var node = <ISyntaxNode>element;
for (var i = 0, n = node.childCount; i < n; i++) {
var child = node.childAt(i);
if (child) {
updateTokenPositionsAndMarkElements(child, changeStart, changeRangeOldEnd, delta, fullStart);
fullStart += fullWidth(child);
}
}
}
}
// else {
// This element ended strictly before the edited range. We don't need to do anything
// with it.
// }
}
}
function forceUpdateTokenPositionsForElement(element: ISyntaxElement, delta: number) {
// No need to move anything if the delta is 0.
if (delta !== 0) {
if (isList(element)) {
var list = <ISyntaxNodeOrToken[]>element;
for (var i = 0, n = list.length; i < n; i++) {
forceUpdateTokenPositionForNodeOrToken(list[i], delta);
}
}
else {
forceUpdateTokenPositionForNodeOrToken(<ISyntaxNodeOrToken>element, delta);
}
}
}
function forceUpdateTokenPosition(token: ISyntaxToken, delta: number) {
token.setFullStart(token.fullStart() + delta);
}
function forceUpdateTokenPositionForNodeOrToken(nodeOrToken: ISyntaxNodeOrToken, delta: number) {
if (isToken(nodeOrToken)) {
forceUpdateTokenPosition(<ISyntaxToken>nodeOrToken, delta);
}
else {
var node = <ISyntaxNode>nodeOrToken;
var tokens = getTokens(node);
for (var i = 0, n = tokens.length; i < n; i++) {
forceUpdateTokenPosition(tokens[i], delta);
}
}
}
function getTokens(node: ISyntaxNode): ISyntaxToken[] {
var tokens = node.__cachedTokens;
if (!tokens) {
tokens = [];
tokenCollectorWalker.tokens = tokens;
visitNodeOrToken(tokenCollectorWalker, node);
node.__cachedTokens = tokens;
tokenCollectorWalker.tokens = undefined;
}
return tokens;
}
export function parse(oldSyntaxTree: SyntaxTree, textChangeRange: TextChangeRange, newText: ISimpleText): SyntaxTree {
if (textChangeRange.isUnchanged()) {

File diff suppressed because it is too large Load Diff

View File

@ -316,8 +316,8 @@ module TypeScript.PrettyPrinter {
this.appendToken(node.closeBraceToken);
}
private appendBlockOrSemicolon(body: BlockSyntax | ISyntaxToken) {
if (body.kind === SyntaxKind.Block) {
private appendBody(body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (body.kind === SyntaxKind.Block || body.kind === SyntaxKind.ExpressionBody) {
this.ensureSpace();
visitNodeOrToken(this, body);
}
@ -326,6 +326,12 @@ module TypeScript.PrettyPrinter {
}
}
public visitExpressionBody(node: ExpressionBody): void {
this.appendToken(node.equalsGreaterThanToken);
this.ensureSpace();
visitNodeOrToken(this, node.expression);
}
public visitFunctionDeclaration(node: FunctionDeclarationSyntax): void {
this.appendSpaceList(node.modifiers);
this.ensureSpace();
@ -333,7 +339,7 @@ module TypeScript.PrettyPrinter {
this.ensureSpace();
this.appendToken(node.identifier);
this.appendNode(node.callSignature);
this.appendBlockOrSemicolon(node.body);
this.appendBody(node.body);
}
public visitVariableStatement(node: VariableStatementSyntax): void {
@ -666,7 +672,7 @@ module TypeScript.PrettyPrinter {
public visitConstructorDeclaration(node: ConstructorDeclarationSyntax): void {
this.appendToken(node.constructorKeyword);
visitNodeOrToken(this, node.callSignature);
this.appendBlockOrSemicolon(node.body);
this.appendBody(node.body);
}
public visitIndexMemberDeclaration(node: IndexMemberDeclarationSyntax): void {
@ -681,7 +687,7 @@ module TypeScript.PrettyPrinter {
this.ensureSpace();
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
this.appendBlockOrSemicolon(node.body);
this.appendBody(node.body);
}
public visitGetAccessor(node: GetAccessorSyntax): void {
@ -692,7 +698,7 @@ module TypeScript.PrettyPrinter {
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
this.ensureSpace();
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitSetAccessor(node: SetAccessorSyntax): void {
@ -703,7 +709,7 @@ module TypeScript.PrettyPrinter {
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature)
this.ensureSpace();
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitMemberVariableDeclaration(node: MemberVariableDeclarationSyntax): void {
@ -936,7 +942,7 @@ module TypeScript.PrettyPrinter {
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
this.ensureSpace();
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitFunctionExpression(node: FunctionExpressionSyntax): void {
@ -949,7 +955,7 @@ module TypeScript.PrettyPrinter {
visitNodeOrToken(this, node.callSignature);
this.ensureSpace();
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitEmptyStatement(node: EmptyStatementSyntax): void {

View File

@ -1430,16 +1430,6 @@ module TypeScript.Scanner {
return !hadError && SyntaxFacts.isIdentifierNameOrAnyKeyword(token) && width(token) === text.length();
}
// A parser source that gets its data from an underlying scanner.
export interface IScannerParserSource extends Parser.IParserSource {
// The position that the scanner is currently at.
absolutePosition(): number;
// Resets the source to this position. Any diagnostics produced after this point will be
// removed.
resetToPosition(absolutePosition: number): void;
}
interface IScannerRewindPoint extends Parser.IRewindPoint {
// Information used by normal parser source.
absolutePosition: number;
@ -1449,7 +1439,7 @@ module TypeScript.Scanner {
// Parser source used in batch scenarios. Directly calls into an underlying text scanner and
// supports none of the functionality to reuse nodes. Good for when you just want want to do
// a single parse of a file.
export function createParserSource(fileName: string, text: ISimpleText, languageVersion: ts.ScriptTarget): IScannerParserSource {
export function createParserSource(fileName: string, text: ISimpleText, languageVersion: ts.ScriptTarget): Parser.IParserSource {
// The absolute position we're at in the text we're reading from.
var _absolutePosition: number = 0;
@ -1489,11 +1479,6 @@ module TypeScript.Scanner {
return undefined;
}
function consumeNode(node: ISyntaxNode): void {
// Should never get called.
throw Errors.invalidOperation();
}
function absolutePosition() {
return _absolutePosition;
}
@ -1561,13 +1546,20 @@ module TypeScript.Scanner {
return slidingWindow.peekItemN(n);
}
function consumeToken(token: ISyntaxToken): void {
// Debug.assert(token.fullWidth() > 0 || token.kind === SyntaxKind.EndOfFileToken);
// Debug.assert(currentToken() === token);
_absolutePosition += token.fullWidth();
slidingWindow.moveToNextItem();
function consumeNodeOrToken(nodeOrToken: ISyntaxNodeOrToken): void {
if (nodeOrToken === slidingWindow.currentItemWithoutFetching()) {
// We're consuming the token that was just fetched from us by the parser. We just
// need to move ourselves forward and ditch this token from the sliding window.
_absolutePosition += (<ISyntaxToken>nodeOrToken).fullWidth();
slidingWindow.moveToNextItem();
}
else {
// We're either consuming a node, or we're consuming a token that wasn't from our
// sliding window. Both cases happen in incremental scenarios when the incremental
// parser uses a node or token from an older tree. In that case, we simply want to
// point ourselves at the end of the element that the parser just consumed.
resetToPosition(fullEnd(nodeOrToken));
}
}
function currentToken(): ISyntaxToken {
@ -1644,15 +1636,13 @@ module TypeScript.Scanner {
currentToken: currentToken,
currentContextualToken: currentContextualToken,
peekToken: peekToken,
consumeNode: consumeNode,
consumeToken: consumeToken,
consumeNodeOrToken: consumeNodeOrToken,
getRewindPoint: getRewindPoint,
rewind: rewind,
releaseRewindPoint: releaseRewindPoint,
tokenDiagnostics: tokenDiagnostics,
release: release,
absolutePosition: absolutePosition,
resetToPosition: resetToPosition,
};
}

View File

@ -163,6 +163,14 @@ module TypeScript {
return this.window[this.currentRelativeItemIndex];
}
public currentItemWithoutFetching(): any {
if (this.currentRelativeItemIndex >= this.windowCount) {
return undefined;
}
return this.window[this.currentRelativeItemIndex];
}
public peekItemN(n: number): any {
// Assert disabled because it is actually expensive enugh to affect perf.
// Debug.assert(n >= 0);

View File

@ -17,40 +17,29 @@ module TypeScript {
return undefined;
}
export function parsedInStrictModeContext(node: ISyntaxNode): boolean {
export function parserContextFlags(node: ISyntaxNode): ParserContextFlags {
var info = node.__data;
if (info === undefined) {
return false;
return 0;
}
return (info & SyntaxNodeConstants.ParsedInStrictModeContext) !== 0;
return info & ParserContextFlags.Mask;
}
export function parsedInStrictModeContext(node: ISyntaxNode): boolean {
return (parserContextFlags(node) & ParserContextFlags.StrictMode) !== 0;
}
export function parsedInDisallowInContext(node: ISyntaxNode): boolean {
var info = node.__data;
if (info === undefined) {
return false;
}
return (info & SyntaxNodeConstants.ParsedInDisallowInContext) !== 0;
return (parserContextFlags(node) & ParserContextFlags.DisallowIn) !== 0;
}
export function parsedInYieldContext(node: ISyntaxNode): boolean {
var info = node.__data;
if (info === undefined) {
return false;
}
return (info & SyntaxNodeConstants.ParsedInYieldContext) !== 0;
return (parserContextFlags(node) & ParserContextFlags.Yield) !== 0;
}
export function parsedInGeneratorParameterContext(node: ISyntaxNode): boolean {
var info = node.__data;
if (info === undefined) {
return false;
}
return (info & SyntaxNodeConstants.ParsedInGeneratorParameterContext) !== 0;
return (parserContextFlags(node) & ParserContextFlags.GeneratorParameter) !== 0;
}
export function previousToken(token: ISyntaxToken): ISyntaxToken {
@ -435,7 +424,7 @@ module TypeScript {
modifiers: ISyntaxToken[];
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface ISwitchClauseSyntax extends ISyntaxNode {

View File

@ -160,7 +160,15 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
<any>{ name: 'identifier', isToken: true },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
<any> {
name: 'ExpressionBody',
baseType: 'ISyntaxNode',
children: [
<any>{ name: 'equalsGreaterThanToken', isToken: true, },
<any>{ name: 'expression', type: 'IExpressionSyntax' }
]
},
<any>{
@ -392,7 +400,8 @@ var definitions:ITypeDefinition[] = [
baseType: 'ISyntaxNode',
interfaces: ['IStatementSyntax'],
children: [
<any>{ name: 'openBraceToken', isToken: true },
<any>{ name: 'equalsGreaterThanToken', isToken: true, isOptional: 'true' },
<any>{ name: 'openBraceToken', isToken: true, },
<any>{ name: 'statements', isList: true, elementType: 'IStatementSyntax' },
<any>{ name: 'closeBraceToken', isToken: true, excludeFromAST: true }
]
@ -435,7 +444,7 @@ var definitions:ITypeDefinition[] = [
children: [
<any>{ name: 'expression', type: 'ILeftHandSideExpressionSyntax' },
<any>{ name: 'openBracketToken', isToken: true, excludeFromAST: true },
<any>{ name: 'argumentExpression', type: 'IExpressionSyntax' },
<any>{ name: 'argumentExpression', type: 'IExpressionSyntax', isOptional: true },
<any>{ name: 'closeBracketToken', isToken: true, excludeFromAST: true }
]
},
@ -635,7 +644,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'modifiers', isList: true, elementType: 'ISyntaxToken' },
<any>{ name: 'constructorKeyword', isToken: true },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -648,7 +657,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'body', type: 'BlockSyntax | ISyntaxToken', isOptional: true }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -661,7 +670,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'getKeyword', isToken: true, excludeFromAST: true },
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'block', type: 'BlockSyntax' }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
<any>{
@ -673,7 +682,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'setKeyword', isToken: true, excludeFromAST: true },
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'block', type: 'BlockSyntax' }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
],
isTypeScriptSpecific: true
},
@ -705,7 +714,7 @@ var definitions:ITypeDefinition[] = [
interfaces: ['IStatementSyntax'],
children: [
<any>{ name: 'throwKeyword', isToken: true, excludeFromAST: true },
<any>{ name: 'expression', type: 'IExpressionSyntax' },
<any>{ name: 'expression', type: 'IExpressionSyntax', isOptional: true },
<any>{ name: 'semicolonToken', isToken: true, isOptional: true, excludeFromAST: true }
]
},
@ -910,7 +919,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
<any>{ name: 'propertyName', type: 'IPropertyNameSyntax' },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'block', type: 'BlockSyntax' }
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }
]
},
<any>{
@ -922,7 +931,7 @@ var definitions:ITypeDefinition[] = [
<any>{ name: 'asterixToken', isToken: true, isOptional: true },
<any>{ name: 'identifier', isToken: true, isOptional: true },
<any>{ name: 'callSignature', type: 'CallSignatureSyntax' },
<any>{ name: 'block', type: 'BlockSyntax' }]
<any>{ name: 'body', type: 'BlockSyntax | ExpressionBody | ISyntaxToken', isOptional: true }]
},
<any>{
name: 'EmptyStatementSyntax',

View File

@ -95,9 +95,9 @@ module TypeScript {
asterixToken: ISyntaxToken;
identifier: ISyntaxToken;
callSignature: CallSignatureSyntax;
body: BlockSyntax | ISyntaxToken;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface FunctionDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken): FunctionDeclarationSyntax }
export interface FunctionDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): FunctionDeclarationSyntax }
export interface ModuleDeclarationSyntax extends ISyntaxNode, IModuleElementSyntax {
modifiers: ISyntaxToken[];
@ -154,9 +154,9 @@ module TypeScript {
asterixToken: ISyntaxToken;
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
body: BlockSyntax | ISyntaxToken;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface MemberFunctionDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken): MemberFunctionDeclarationSyntax }
export interface MemberFunctionDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): MemberFunctionDeclarationSyntax }
export interface MemberVariableDeclarationSyntax extends ISyntaxNode, IMemberDeclarationSyntax {
modifiers: ISyntaxToken[];
@ -169,9 +169,9 @@ module TypeScript {
modifiers: ISyntaxToken[];
constructorKeyword: ISyntaxToken;
callSignature: CallSignatureSyntax;
body: BlockSyntax | ISyntaxToken;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface ConstructorDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], constructorKeyword: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken): ConstructorDeclarationSyntax }
export interface ConstructorDeclarationConstructor { new (data: number, modifiers: ISyntaxToken[], constructorKeyword: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): ConstructorDeclarationSyntax }
export interface IndexMemberDeclarationSyntax extends ISyntaxNode, IClassElementSyntax {
modifiers: ISyntaxToken[];
@ -185,18 +185,18 @@ module TypeScript {
getKeyword: ISyntaxToken;
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface GetAccessorConstructor { new (data: number, modifiers: ISyntaxToken[], getKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax): GetAccessorSyntax }
export interface GetAccessorConstructor { new (data: number, modifiers: ISyntaxToken[], getKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): GetAccessorSyntax }
export interface SetAccessorSyntax extends ISyntaxNode, IAccessorSyntax {
modifiers: ISyntaxToken[];
setKeyword: ISyntaxToken;
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface SetAccessorConstructor { new (data: number, modifiers: ISyntaxToken[], setKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax): SetAccessorSyntax }
export interface SetAccessorConstructor { new (data: number, modifiers: ISyntaxToken[], setKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): SetAccessorSyntax }
export interface PropertySignatureSyntax extends ISyntaxNode, ITypeMemberSyntax {
propertyName: IPropertyNameSyntax;
@ -234,11 +234,12 @@ module TypeScript {
export interface MethodSignatureConstructor { new (data: number, propertyName: IPropertyNameSyntax, questionToken: ISyntaxToken, callSignature: CallSignatureSyntax): MethodSignatureSyntax }
export interface BlockSyntax extends ISyntaxNode, IStatementSyntax {
equalsGreaterThanToken: ISyntaxToken;
openBraceToken: ISyntaxToken;
statements: IStatementSyntax[];
closeBraceToken: ISyntaxToken;
}
export interface BlockConstructor { new (data: number, openBraceToken: ISyntaxToken, statements: IStatementSyntax[], closeBraceToken: ISyntaxToken): BlockSyntax }
export interface BlockConstructor { new (data: number, equalsGreaterThanToken: ISyntaxToken, openBraceToken: ISyntaxToken, statements: IStatementSyntax[], closeBraceToken: ISyntaxToken): BlockSyntax }
export interface IfStatementSyntax extends ISyntaxNode, IStatementSyntax {
ifKeyword: ISyntaxToken;
@ -503,9 +504,9 @@ module TypeScript {
asterixToken: ISyntaxToken;
identifier: ISyntaxToken;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface FunctionExpressionConstructor { new (data: number, functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, block: BlockSyntax): FunctionExpressionSyntax }
export interface FunctionExpressionConstructor { new (data: number, functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): FunctionExpressionSyntax }
export interface OmittedExpressionSyntax extends ISyntaxNode, IExpressionSyntax {
}
@ -650,9 +651,9 @@ module TypeScript {
asterixToken: ISyntaxToken;
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface FunctionPropertyAssignmentConstructor { new (data: number, asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax): FunctionPropertyAssignmentSyntax }
export interface FunctionPropertyAssignmentConstructor { new (data: number, asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken): FunctionPropertyAssignmentSyntax }
export interface ParameterSyntax extends ISyntaxNode {
dotDotDotToken: ISyntaxToken;
@ -676,6 +677,12 @@ module TypeScript {
}
export interface TypeAnnotationConstructor { new (data: number, colonToken: ISyntaxToken, type: ITypeSyntax): TypeAnnotationSyntax }
export interface ExpressionBody extends ISyntaxNode {
equalsGreaterThanToken: ISyntaxToken;
expression: IExpressionSyntax;
}
export interface ExpressionBodyConstructor { new (data: number, equalsGreaterThanToken: ISyntaxToken, expression: IExpressionSyntax): ExpressionBody }
export interface ComputedPropertyNameSyntax extends ISyntaxNode, IPropertyNameSyntax {
openBracketToken: ISyntaxToken;
expression: IExpressionSyntax;

View File

@ -268,6 +268,7 @@ module TypeScript {
Parameter,
EnumElement,
TypeAnnotation,
ExpressionBody,
ComputedPropertyName,
ExternalModuleReference,
ModuleNameModuleReference,

View File

@ -38,7 +38,7 @@ module TypeScript {
module TypeScript.Syntax {
function addArrayPrototypeValue(name: string, val: any) {
if (Object.defineProperty && (<any>Array.prototype)[name] === undefined) {
Object.defineProperty(Array.prototype, name, { value: val, writable: false });
Object.defineProperty(Array.prototype, name, { value: val, writable: false, enumerable: false });
}
else {
(<any>Array.prototype)[name] = val;

View File

@ -238,7 +238,7 @@ module TypeScript {
}
}
export var FunctionDeclarationSyntax: FunctionDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken) {
export var FunctionDeclarationSyntax: FunctionDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.modifiers = modifiers,
this.functionKeyword = functionKeyword,
@ -406,7 +406,7 @@ module TypeScript {
}
}
export var MemberFunctionDeclarationSyntax: MemberFunctionDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken) {
export var MemberFunctionDeclarationSyntax: MemberFunctionDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.modifiers = modifiers,
this.asterixToken = asterixToken,
@ -450,7 +450,7 @@ module TypeScript {
}
}
export var ConstructorDeclarationSyntax: ConstructorDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], constructorKeyword: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ISyntaxToken) {
export var ConstructorDeclarationSyntax: ConstructorDeclarationConstructor = <any>function(data: number, modifiers: ISyntaxToken[], constructorKeyword: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.modifiers = modifiers,
this.constructorKeyword = constructorKeyword,
@ -491,18 +491,18 @@ module TypeScript {
}
}
export var GetAccessorSyntax: GetAccessorConstructor = <any>function(data: number, modifiers: ISyntaxToken[], getKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax) {
export var GetAccessorSyntax: GetAccessorConstructor = <any>function(data: number, modifiers: ISyntaxToken[], getKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.modifiers = modifiers,
this.getKeyword = getKeyword,
this.propertyName = propertyName,
this.callSignature = callSignature,
this.block = block,
this.body = body,
modifiers.parent = this,
getKeyword.parent = this,
propertyName.parent = this,
callSignature.parent = this,
block.parent = this;
body && (body.parent = this);
};
GetAccessorSyntax.prototype.kind = SyntaxKind.GetAccessor;
GetAccessorSyntax.prototype.childCount = 5;
@ -512,22 +512,22 @@ module TypeScript {
case 1: return this.getKeyword;
case 2: return this.propertyName;
case 3: return this.callSignature;
case 4: return this.block;
case 4: return this.body;
}
}
export var SetAccessorSyntax: SetAccessorConstructor = <any>function(data: number, modifiers: ISyntaxToken[], setKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax) {
export var SetAccessorSyntax: SetAccessorConstructor = <any>function(data: number, modifiers: ISyntaxToken[], setKeyword: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.modifiers = modifiers,
this.setKeyword = setKeyword,
this.propertyName = propertyName,
this.callSignature = callSignature,
this.block = block,
this.body = body,
modifiers.parent = this,
setKeyword.parent = this,
propertyName.parent = this,
callSignature.parent = this,
block.parent = this;
body && (body.parent = this);
};
SetAccessorSyntax.prototype.kind = SyntaxKind.SetAccessor;
SetAccessorSyntax.prototype.childCount = 5;
@ -537,7 +537,7 @@ module TypeScript {
case 1: return this.setKeyword;
case 2: return this.propertyName;
case 3: return this.callSignature;
case 4: return this.block;
case 4: return this.body;
}
}
@ -636,22 +636,25 @@ module TypeScript {
}
}
export var BlockSyntax: BlockConstructor = <any>function(data: number, openBraceToken: ISyntaxToken, statements: IStatementSyntax[], closeBraceToken: ISyntaxToken) {
export var BlockSyntax: BlockConstructor = <any>function(data: number, equalsGreaterThanToken: ISyntaxToken, openBraceToken: ISyntaxToken, statements: IStatementSyntax[], closeBraceToken: ISyntaxToken) {
if (data) { this.__data = data; }
this.equalsGreaterThanToken = equalsGreaterThanToken,
this.openBraceToken = openBraceToken,
this.statements = statements,
this.closeBraceToken = closeBraceToken,
equalsGreaterThanToken && (equalsGreaterThanToken.parent = this),
openBraceToken.parent = this,
statements.parent = this,
closeBraceToken.parent = this;
};
BlockSyntax.prototype.kind = SyntaxKind.Block;
BlockSyntax.prototype.childCount = 3;
BlockSyntax.prototype.childCount = 4;
BlockSyntax.prototype.childAt = function(index: number): ISyntaxElement {
switch (index) {
case 0: return this.openBraceToken;
case 1: return this.statements;
case 2: return this.closeBraceToken;
case 0: return this.equalsGreaterThanToken;
case 1: return this.openBraceToken;
case 2: return this.statements;
case 3: return this.closeBraceToken;
}
}
@ -893,7 +896,7 @@ module TypeScript {
this.expression = expression,
this.semicolonToken = semicolonToken,
throwKeyword.parent = this,
expression.parent = this,
expression && (expression.parent = this),
semicolonToken && (semicolonToken.parent = this);
};
ThrowStatementSyntax.prototype.kind = SyntaxKind.ThrowStatement;
@ -1347,7 +1350,7 @@ module TypeScript {
this.closeBracketToken = closeBracketToken,
expression.parent = this,
openBracketToken.parent = this,
argumentExpression.parent = this,
argumentExpression && (argumentExpression.parent = this),
closeBracketToken.parent = this;
};
ElementAccessExpressionSyntax.prototype.kind = SyntaxKind.ElementAccessExpression;
@ -1361,18 +1364,18 @@ module TypeScript {
}
}
export var FunctionExpressionSyntax: FunctionExpressionConstructor = <any>function(data: number, functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, block: BlockSyntax) {
export var FunctionExpressionSyntax: FunctionExpressionConstructor = <any>function(data: number, functionKeyword: ISyntaxToken, asterixToken: ISyntaxToken, identifier: ISyntaxToken, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.functionKeyword = functionKeyword,
this.asterixToken = asterixToken,
this.identifier = identifier,
this.callSignature = callSignature,
this.block = block,
this.body = body,
functionKeyword.parent = this,
asterixToken && (asterixToken.parent = this),
identifier && (identifier.parent = this),
callSignature.parent = this,
block.parent = this;
body && (body.parent = this);
};
FunctionExpressionSyntax.prototype.kind = SyntaxKind.FunctionExpression;
FunctionExpressionSyntax.prototype.childCount = 5;
@ -1382,7 +1385,7 @@ module TypeScript {
case 1: return this.asterixToken;
case 2: return this.identifier;
case 3: return this.callSignature;
case 4: return this.block;
case 4: return this.body;
}
}
@ -1760,16 +1763,16 @@ module TypeScript {
}
}
export var FunctionPropertyAssignmentSyntax: FunctionPropertyAssignmentConstructor = <any>function(data: number, asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, block: BlockSyntax) {
export var FunctionPropertyAssignmentSyntax: FunctionPropertyAssignmentConstructor = <any>function(data: number, asterixToken: ISyntaxToken, propertyName: IPropertyNameSyntax, callSignature: CallSignatureSyntax, body: BlockSyntax | ExpressionBody | ISyntaxToken) {
if (data) { this.__data = data; }
this.asterixToken = asterixToken,
this.propertyName = propertyName,
this.callSignature = callSignature,
this.block = block,
this.body = body,
asterixToken && (asterixToken.parent = this),
propertyName.parent = this,
callSignature.parent = this,
block.parent = this;
body && (body.parent = this);
};
FunctionPropertyAssignmentSyntax.prototype.kind = SyntaxKind.FunctionPropertyAssignment;
FunctionPropertyAssignmentSyntax.prototype.childCount = 4;
@ -1778,7 +1781,7 @@ module TypeScript {
case 0: return this.asterixToken;
case 1: return this.propertyName;
case 2: return this.callSignature;
case 3: return this.block;
case 3: return this.body;
}
}
@ -1842,6 +1845,22 @@ module TypeScript {
}
}
export var ExpressionBody: ExpressionBodyConstructor = <any>function(data: number, equalsGreaterThanToken: ISyntaxToken, expression: IExpressionSyntax) {
if (data) { this.__data = data; }
this.equalsGreaterThanToken = equalsGreaterThanToken,
this.expression = expression,
equalsGreaterThanToken.parent = this,
expression.parent = this;
};
ExpressionBody.prototype.kind = SyntaxKind.ExpressionBody;
ExpressionBody.prototype.childCount = 2;
ExpressionBody.prototype.childAt = function(index: number): ISyntaxElement {
switch (index) {
case 0: return this.equalsGreaterThanToken;
case 1: return this.expression;
}
}
export var ComputedPropertyNameSyntax: ComputedPropertyNameConstructor = <any>function(data: number, openBracketToken: ISyntaxToken, expression: IExpressionSyntax, closeBracketToken: ISyntaxToken) {
if (data) { this.__data = data; }
this.openBracketToken = openBracketToken,

View File

@ -290,8 +290,8 @@ module TypeScript.Syntax {
return new RealizedToken(token.fullStart(), token.kind, token.isKeywordConvertedToIdentifier(), leadingTrivia, token.text());
}
export function emptyToken(kind: SyntaxKind): ISyntaxToken {
return new EmptyToken(kind);
export function emptyToken(kind: SyntaxKind, fullStart: number): ISyntaxToken {
return new EmptyToken(kind, fullStart);
}
class EmptyToken implements ISyntaxToken {
@ -300,17 +300,17 @@ module TypeScript.Syntax {
public parent: ISyntaxElement;
public childCount: number;
constructor(public kind: SyntaxKind) {
constructor(public kind: SyntaxKind, private _fullStart: number) {
}
public setFullStart(fullStart: number): void {
// An empty token is always at the -1 position.
this._fullStart = fullStart;
}
public childAt(index: number): ISyntaxElement { throw Errors.invalidOperation() }
public clone(): ISyntaxToken {
return new EmptyToken(this.kind);
return new EmptyToken(this.kind, this._fullStart);
}
// Empty tokens are never incrementally reusable.
@ -321,75 +321,7 @@ module TypeScript.Syntax {
}
public fullWidth() { return 0; }
private position(): number {
// It's hard for us to tell the position of an empty token at the eact time we create
// it. For example, we may have:
//
// a / finally
//
// There will be a missing token detected after the forward slash, so it would be
// tempting to set its position as the full-end of hte slash token. However,
// immediately after that, the 'finally' token will be skipped and will be attached
// as skipped text to the forward slash. This means the 'full-end' of the forward
// slash will change, and thus the empty token will now appear to be embedded inside
// another token. This violates are rule that all tokens must only touch at the end,
// and makes enforcing invariants much harder.
//
// To address this we create the empty token with no known position, and then we
// determine what it's position should be based on where it lies in the tree.
// Specifically, we find the previous non-zero-width syntax element, and we consider
// the full-start of this token to be at the full-end of that element.
var previousElement = this.previousNonZeroWidthElement();
return !previousElement ? 0 : fullStart(previousElement) + fullWidth(previousElement);
}
private previousNonZeroWidthElement(): ISyntaxElement {
var current: ISyntaxElement = this;
while (true) {
var parent = current.parent;
if (parent === undefined) {
Debug.assert(current.kind === SyntaxKind.SourceUnit, "We had a node without a parent that was not the root node!");
// We walked all the way to the top, and never found a previous element. This
// can happen with code like:
//
// / b;
//
// We will have an empty identifier token as the first token in the tree. In
// this case, return undefined so that the position of the empty token will be
// considered to be 0.
return undefined;
}
// Ok. We have a parent. First, find out which slot we're at in the parent.
for (var i = 0, n = childCount(parent); i < n; i++) {
if (childAt(parent, i) === current) {
break;
}
}
Debug.assert(i !== n, "Could not find current element in parent's child list!");
// Walk backward from this element, looking for a non-zero-width sibling.
for (var j = i - 1; j >= 0; j--) {
var sibling = childAt(parent, j);
if (sibling && fullWidth(sibling) > 0) {
return sibling;
}
}
// We couldn't find a non-zero-width sibling. We were either the first element, or
// all preceding elements are empty. So, move up to our parent so we we can find
// its preceding sibling.
current = current.parent;
}
}
public fullStart(): number {
return this.position();
}
public fullStart(): number { return this._fullStart; }
public text() { return ""; }
public fullText(): string { return ""; }

View File

@ -138,8 +138,12 @@ module TypeScript {
}
private pushDiagnostic(element: ISyntaxElement, diagnosticKey: string, args?: any[]): void {
this.pushDiagnosticAt(start(element, this.text), width(element), diagnosticKey, args);
}
private pushDiagnosticAt(start: number, length: number, diagnosticKey: string, args?: any[]): void {
this.diagnostics.push(new Diagnostic(
this.syntaxTree.fileName(), this.syntaxTree.lineMap(), start(element, this.text), width(element), diagnosticKey, args));
this.syntaxTree.fileName(), this.syntaxTree.lineMap(), start, length, diagnosticKey, args));
}
public visitCatchClause(node: CatchClauseSyntax): void {
@ -631,13 +635,27 @@ module TypeScript {
this.checkClassElementModifiers(node.modifiers) ||
this.checkForDisallowedAccessorTypeParameters(node.callSignature) ||
this.checkGetAccessorParameter(node) ||
this.checkForDisallowedTemplatePropertyName(node.propertyName)) {
this.checkForDisallowedTemplatePropertyName(node.propertyName) ||
this.checkForSemicolonInsteadOfBlock(node, node.body)) {
return;
}
super.visitGetAccessor(node);
}
private checkForSemicolonInsteadOfBlock(parent: ISyntaxNode, node: BlockSyntax | ExpressionBody | ISyntaxToken): boolean {
if (node === undefined) {
this.pushDiagnosticAt(fullEnd(parent), 0, DiagnosticCode._0_expected, ["{"]);
return true;
}
else if (node.kind === SyntaxKind.SemicolonToken) {
this.pushDiagnostic(node, DiagnosticCode._0_expected, ["{"]);
return true;
}
return false;
}
private checkForDisallowedSetAccessorTypeAnnotation(accessor: SetAccessorSyntax): boolean {
if (accessor.callSignature.typeAnnotation) {
this.pushDiagnostic(accessor.callSignature.typeAnnotation, DiagnosticCode.Type_annotation_cannot_appear_on_a_set_accessor);
@ -708,13 +726,41 @@ module TypeScript {
this.checkForDisallowedAccessorTypeParameters(node.callSignature) ||
this.checkForDisallowedSetAccessorTypeAnnotation(node) ||
this.checkSetAccessorParameter(node) ||
this.checkForDisallowedTemplatePropertyName(node.propertyName)) {
this.checkForDisallowedTemplatePropertyName(node.propertyName) ||
this.checkForSemicolonInsteadOfBlock(node, node.body)) {
return;
}
super.visitSetAccessor(node);
}
public visitElementAccessExpression(node: ElementAccessExpressionSyntax): void {
if (this.checkForMissingArgumentExpression(node)) {
return;
}
super.visitElementAccessExpression(node);
}
public checkForMissingArgumentExpression(node: ElementAccessExpressionSyntax): boolean {
if (node.argumentExpression === undefined) {
if (node.parent.kind === SyntaxKind.ObjectCreationExpression && (<ObjectCreationExpressionSyntax>node.parent).expression === node) {
// Provide a specialized message for the very common case where someone writes:
// new Foo[]
var start = TypeScript.start(node.openBracketToken);
var end = TypeScript.fullEnd(node.closeBracketToken);
this.pushDiagnosticAt(start, end - start, DiagnosticCode.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead);
}
else {
this.pushDiagnostic(node.closeBracketToken, DiagnosticCode.Expression_expected);
}
return true;
}
return false;
}
public visitEnumDeclaration(node: EnumDeclarationSyntax): void {
if (this.checkForDisallowedDeclareModifier(node.modifiers) ||
this.checkForRequiredDeclareModifier(node, node.identifier, node.modifiers) ||
@ -887,7 +933,8 @@ module TypeScript {
}
public visitBlock(node: BlockSyntax): void {
if (this.checkForBlockInAmbientContext(node)) {
if (this.checkForBlockInAmbientContext(node) ||
this.checkForMalformedBlock(node)) {
return;
}
@ -897,6 +944,15 @@ module TypeScript {
this.inBlock = savedInBlock;
}
public checkForMalformedBlock(node: BlockSyntax): boolean {
if (node.equalsGreaterThanToken || node.openBraceToken === undefined) {
this.pushDiagnostic(firstToken(node), DiagnosticCode._0_expected, ["{"]);
return true;
}
return false;
}
private checkForBlockInAmbientContext(node: BlockSyntax): boolean {
if (this.inAmbientDeclaration || this.syntaxTree.isDeclaration()) {
// Provide a specialized message for a block as a statement versus the block as a
@ -923,6 +979,11 @@ module TypeScript {
return false;
}
public visitExpressionBody(node: ExpressionBody): void {
// These are always errors. So no need to ever recurse on them.
this.pushDiagnostic(node.equalsGreaterThanToken, DiagnosticCode._0_expected, ["{"]);
}
public visitBreakStatement(node: BreakStatementSyntax): void {
if (this.checkForStatementInAmbientContxt(node) ||
this.checkBreakStatementTarget(node)) {
@ -1264,13 +1325,23 @@ module TypeScript {
}
public visitThrowStatement(node: ThrowStatementSyntax): void {
if (this.checkForStatementInAmbientContxt(node)) {
if (this.checkForStatementInAmbientContxt(node) ||
this.checkForMissingThrowStatementExpression(node)) {
return;
}
super.visitThrowStatement(node);
}
public checkForMissingThrowStatementExpression(node: ThrowStatementSyntax): boolean {
if (node.expression === undefined) {
this.pushDiagnosticAt(fullEnd(node.throwKeyword), 0, DiagnosticCode.Expression_expected);
return true;
}
return false;
}
public visitTryStatement(node: TryStatementSyntax): void {
if (this.checkForStatementInAmbientContxt(node)) {
return;
@ -1333,7 +1404,8 @@ module TypeScript {
}
public visitFunctionExpression(node: FunctionExpressionSyntax): void {
if (this.checkForDisallowedEvalOrArguments(node, node.identifier)) {
if (this.checkForDisallowedEvalOrArguments(node, node.identifier) ||
this.checkForSemicolonInsteadOfBlock(node, node.body)) {
return;
}
@ -1341,7 +1413,8 @@ module TypeScript {
}
public visitFunctionPropertyAssignment(node: FunctionPropertyAssignmentSyntax): void {
if (this.checkForDisallowedTemplatePropertyName(node.propertyName)) {
if (this.checkForDisallowedTemplatePropertyName(node.propertyName) ||
this.checkForSemicolonInsteadOfBlock(node, node.body)) {
return;
}

View File

@ -94,6 +94,7 @@ module TypeScript {
case SyntaxKind.Parameter: return visitor.visitParameter(<ParameterSyntax>element);
case SyntaxKind.EnumElement: return visitor.visitEnumElement(<EnumElementSyntax>element);
case SyntaxKind.TypeAnnotation: return visitor.visitTypeAnnotation(<TypeAnnotationSyntax>element);
case SyntaxKind.ExpressionBody: return visitor.visitExpressionBody(<ExpressionBody>element);
case SyntaxKind.ComputedPropertyName: return visitor.visitComputedPropertyName(<ComputedPropertyNameSyntax>element);
case SyntaxKind.ExternalModuleReference: return visitor.visitExternalModuleReference(<ExternalModuleReferenceSyntax>element);
case SyntaxKind.ModuleNameModuleReference: return visitor.visitModuleNameModuleReference(<ModuleNameModuleReferenceSyntax>element);
@ -193,6 +194,7 @@ module TypeScript {
visitParameter(node: ParameterSyntax): any;
visitEnumElement(node: EnumElementSyntax): any;
visitTypeAnnotation(node: TypeAnnotationSyntax): any;
visitExpressionBody(node: ExpressionBody): any;
visitComputedPropertyName(node: ComputedPropertyNameSyntax): any;
visitExternalModuleReference(node: ExternalModuleReferenceSyntax): any;
visitModuleNameModuleReference(node: ModuleNameModuleReferenceSyntax): any;

View File

@ -180,7 +180,7 @@ module TypeScript {
this.visitToken(node.getKeyword);
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitSetAccessor(node: SetAccessorSyntax): void {
@ -188,7 +188,7 @@ module TypeScript {
this.visitToken(node.setKeyword);
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitPropertySignature(node: PropertySignatureSyntax): void {
@ -222,6 +222,7 @@ module TypeScript {
}
public visitBlock(node: BlockSyntax): void {
this.visitOptionalToken(node.equalsGreaterThanToken);
this.visitToken(node.openBraceToken);
this.visitList(node.statements);
this.visitToken(node.closeBraceToken);
@ -456,7 +457,7 @@ module TypeScript {
this.visitOptionalToken(node.asterixToken);
this.visitOptionalToken(node.identifier);
visitNodeOrToken(this, node.callSignature);
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitOmittedExpression(node: OmittedExpressionSyntax): void {
@ -581,7 +582,7 @@ module TypeScript {
this.visitOptionalToken(node.asterixToken);
visitNodeOrToken(this, node.propertyName);
visitNodeOrToken(this, node.callSignature);
visitNodeOrToken(this, node.block);
visitNodeOrToken(this, node.body);
}
public visitParameter(node: ParameterSyntax): void {
@ -603,6 +604,11 @@ module TypeScript {
visitNodeOrToken(this, node.type);
}
public visitExpressionBody(node: ExpressionBody): void {
this.visitToken(node.equalsGreaterThanToken);
visitNodeOrToken(this, node.expression);
}
public visitComputedPropertyName(node: ComputedPropertyNameSyntax): void {
this.visitToken(node.openBracketToken);
visitNodeOrToken(this, node.expression);

View File

@ -320,4 +320,9 @@ module ts {
export function isPunctuation(kind: SyntaxKind): boolean {
return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation;
}
export function isInsideTemplateLiteral(node: LiteralExpression, position: number) {
return (node.getStart() < position && position < node.getEnd())
|| (isUnterminatedTemplateEnd(node) && position === node.getEnd());
}
}

View File

@ -0,0 +1,9 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName10_es6.ts(2,8): error TS1005: ';' expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName10_es6.ts (1 errors) ====
class C {
[e] = 1
~
!!! error TS1005: ';' expected.
}

View File

@ -0,0 +1,15 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName11_es6.ts(2,7): error TS1005: ';' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName11_es6.ts(2,8): error TS1109: Expression expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName11_es6.ts(3,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName11_es6.ts (3 errors) ====
class C {
[e]();
~
!!! error TS1005: ';' expected.
~
!!! error TS1109: Expression expected.
}
~
!!! error TS1128: Declaration or statement expected.

View File

@ -0,0 +1,15 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName12_es6.ts(2,7): error TS1005: ';' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName12_es6.ts(2,10): error TS1005: '=>' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName12_es6.ts(3,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName12_es6.ts (3 errors) ====
class C {
[e]() { }
~
!!! error TS1005: ';' expected.
~
!!! error TS1005: '=>' expected.
}
~
!!! error TS1128: Declaration or statement expected.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName13_es6.ts(1,11): error TS1022: An index signature parameter must have a type annotation.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName13_es6.ts (1 errors) ====
var v: { [e]: number };
~
!!! error TS1022: An index signature parameter must have a type annotation.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName14_es6.ts(1,13): error TS1005: ';' expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName14_es6.ts (1 errors) ====
var v: { [e](): number };
~
!!! error TS1005: ';' expected.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName15_es6.ts(1,32): error TS1022: An index signature parameter must have a type annotation.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName15_es6.ts (1 errors) ====
var v: { [e: number]: string; [e]: number };
~
!!! error TS1022: An index signature parameter must have a type annotation.

View File

@ -0,0 +1,18 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName16_es6.ts(2,3): error TS1132: Enum member expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName16_es6.ts(3,1): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName16_es6.ts(2,3): error TS2364: Invalid left-hand side of assignment expression.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName16_es6.ts(2,4): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName16_es6.ts (4 errors) ====
enum E {
[e] = 1
~
!!! error TS1132: Enum member expected.
~~~
!!! error TS2364: Invalid left-hand side of assignment expression.
~
!!! error TS2304: Cannot find name 'e'.
}
~
!!! error TS1128: Declaration or statement expected.

View File

@ -0,0 +1,16 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName17_es6.ts(1,15): error TS1003: Identifier expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName17_es6.ts(1,22): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName17_es6.ts(1,26): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName17_es6.ts(1,16): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName17_es6.ts (4 errors) ====
var v = { set [e](v) { } }
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName18_es6.ts(1,13): error TS1005: ';' expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName18_es6.ts (1 errors) ====
var v: { [e]?(): number };
~
!!! error TS1005: ';' expected.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName19_es6.ts(1,13): error TS1005: ';' expected.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName19_es6.ts (1 errors) ====
var v: { [e]? };
~
!!! error TS1005: ';' expected.

View File

@ -0,0 +1,13 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName1_es6.ts(1,11): error TS1136: Property assignment expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName1_es6.ts(1,15): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName1_es6.ts(1,12): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName1_es6.ts (3 errors) ====
var v = { [e] };
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,19 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts(1,11): error TS1136: Property assignment expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts(1,14): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts(1,16): error TS1134: Variable declaration expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts(1,18): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts(1,12): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName2_es6.ts (5 errors) ====
var v = { [e]: 1 };
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1134: Variable declaration expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,16 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName3_es6.ts(1,11): error TS1136: Property assignment expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName3_es6.ts(1,17): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName3_es6.ts(1,21): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName3_es6.ts(1,12): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName3_es6.ts (4 errors) ====
var v = { [e]() { } };
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,16 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName4_es6.ts(1,15): error TS1003: Identifier expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName4_es6.ts(1,21): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName4_es6.ts(1,25): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName4_es6.ts(1,16): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName4_es6.ts (4 errors) ====
var v = { get [e]() { } };
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,19 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts(1,18): error TS1005: ':' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts(1,28): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts(1,32): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts(1,18): error TS2304: Cannot find name 'get'.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts(1,23): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName5_es6.ts (5 errors) ====
var v = { public get [e]() { } };
~~~
!!! error TS1005: ':' expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~~~
!!! error TS2304: Cannot find name 'get'.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,28 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,11): error TS1136: Property assignment expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,14): error TS1005: ',' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,16): error TS1134: Variable declaration expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,26): error TS1005: ';' expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,30): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,12): error TS2304: Cannot find name 'e'.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,20): error TS2304: Cannot find name 'e'.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts(1,24): error TS2304: Cannot find name 'e'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName6_es6.ts (8 errors) ====
var v = { [e]: 1, [e + e]: 2 };
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1134: Variable declaration expected.
~
!!! error TS1005: ';' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'e'.
~
!!! error TS2304: Cannot find name 'e'.
~
!!! error TS2304: Cannot find name 'e'.

View File

@ -0,0 +1,9 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName7_es6.ts(2,5): error TS1022: An index signature parameter must have a type annotation.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName7_es6.ts (1 errors) ====
class C {
[e]
~
!!! error TS1022: An index signature parameter must have a type annotation.
}

View File

@ -0,0 +1,9 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName8_es6.ts(2,12): error TS1022: An index signature parameter must have a type annotation.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName8_es6.ts (1 errors) ====
class C {
public [e]
~
!!! error TS1022: An index signature parameter must have a type annotation.
}

View File

@ -0,0 +1,12 @@
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName9_es6.ts(2,5): error TS1022: An index signature parameter must have a type annotation.
tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName9_es6.ts(2,9): error TS2304: Cannot find name 'Type'.
==== tests/cases/conformance/es6/computedPropertyNames/ComputedPropertyName9_es6.ts (2 errors) ====
class C {
[e]: Type
~
!!! error TS1022: An index signature parameter must have a type annotation.
~~~~
!!! error TS2304: Cannot find name 'Type'.
}

View File

@ -0,0 +1,8 @@
//// [FunctionDeclaration10_es6.ts]
function * foo(a = yield => yield) {
}
//// [FunctionDeclaration10_es6.js]
function foo(a) {
if (a === void 0) { a = function (yield) { return yield; }; }
}

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts ===
function * foo(a = yield => yield) {
>foo : (a?: (yield: any) => any) => void
>a : (yield: any) => any
>yield => yield : (yield: any) => any
>yield : any
>yield : any
}

View File

@ -0,0 +1,7 @@
//// [FunctionDeclaration11_es6.ts]
function * yield() {
}
//// [FunctionDeclaration11_es6.js]
function yield() {
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration11_es6.ts ===
function * yield() {
>yield : () => void
}

View File

@ -0,0 +1,13 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,20): error TS1005: '(' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,25): error TS1005: '=' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts(1,28): error TS1005: '=>' expected.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration12_es6.ts (3 errors) ====
var v = function * yield() { }
~~~~~
!!! error TS1005: '(' expected.
~
!!! error TS1005: '=' expected.
~
!!! error TS1005: '=>' expected.

View File

@ -0,0 +1,11 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts(3,11): error TS2304: Cannot find name 'yield'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts (1 errors) ====
function * foo() {
// Legal to use 'yield' in a type context.
var v: yield;
~~~~~
!!! error TS2304: Cannot find name 'yield'.
}

View File

@ -0,0 +1,12 @@
//// [FunctionDeclaration13_es6.ts]
function * foo() {
// Legal to use 'yield' in a type context.
var v: yield;
}
//// [FunctionDeclaration13_es6.js]
function foo() {
// Legal to use 'yield' in a type context.
var v;
}

View File

@ -0,0 +1,7 @@
//// [FunctionDeclaration1_es6.ts]
function * foo() {
}
//// [FunctionDeclaration1_es6.js]
function foo() {
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration1_es6.ts ===
function * foo() {
>foo : () => void
}

View File

@ -0,0 +1,7 @@
//// [FunctionDeclaration2_es6.ts]
function f(yield) {
}
//// [FunctionDeclaration2_es6.js]
function f(yield) {
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration2_es6.ts ===
function f(yield) {
>f : (yield: any) => void
>yield : any
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'yield' cannot be referenced in its initializer.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration3_es6.ts (1 errors) ====
function f(yield = yield) {
~~~~~
!!! error TS2372: Parameter 'yield' cannot be referenced in its initializer.
}

View File

@ -0,0 +1,8 @@
//// [FunctionDeclaration3_es6.ts]
function f(yield = yield) {
}
//// [FunctionDeclaration3_es6.js]
function f(yield) {
if (yield === void 0) { yield = yield; }
}

View File

@ -0,0 +1,7 @@
//// [FunctionDeclaration4_es6.ts]
function yield() {
}
//// [FunctionDeclaration4_es6.js]
function yield() {
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration4_es6.ts ===
function yield() {
>yield : () => void
}

View File

@ -0,0 +1,17 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration5_es6.ts(1,14): error TS1138: Parameter declaration expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration5_es6.ts(1,19): error TS1005: ';' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration5_es6.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration5_es6.ts(1,14): error TS2304: Cannot find name 'yield'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration5_es6.ts (4 errors) ====
function*foo(yield) {
~~~~~
!!! error TS1138: Parameter declaration expected.
~
!!! error TS1005: ';' expected.
~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
~~~~~
!!! error TS2304: Cannot find name 'yield'.
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,18): error TS2304: Cannot find name 'yield'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts (1 errors) ====
function*foo(a = yield) {
~~~~~
!!! error TS2304: Cannot find name 'yield'.
}

View File

@ -0,0 +1,8 @@
//// [FunctionDeclaration6_es6.ts]
function*foo(a = yield) {
}
//// [FunctionDeclaration6_es6.js]
function foo(a) {
if (a === void 0) { a = yield; }
}

View File

@ -0,0 +1,11 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,20): error TS2304: Cannot find name 'yield'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts (1 errors) ====
function*bar() {
// 'yield' here is an identifier, and not a yield expression.
function*foo(a = yield) {
~~~~~
!!! error TS2304: Cannot find name 'yield'.
}
}

View File

@ -0,0 +1,14 @@
//// [FunctionDeclaration7_es6.ts]
function*bar() {
// 'yield' here is an identifier, and not a yield expression.
function*foo(a = yield) {
}
}
//// [FunctionDeclaration7_es6.js]
function bar() {
// 'yield' here is an identifier, and not a yield expression.
function foo(a) {
if (a === void 0) { a = yield; }
}
}

View File

@ -0,0 +1,16 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,11): error TS1136: Property assignment expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,18): error TS1005: ',' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,24): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,12): error TS2304: Cannot find name 'yield'.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts (4 errors) ====
var v = { [yield]: foo }
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~~~~~
!!! error TS2304: Cannot find name 'yield'.

View File

@ -0,0 +1,15 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(2,13): error TS1136: Property assignment expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(2,20): error TS1005: ',' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(3,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts (3 errors) ====
function * foo() {
var v = { [yield]: foo }
~
!!! error TS1136: Property assignment expected.
~
!!! error TS1005: ',' expected.
}
~
!!! error TS1128: Declaration or statement expected.

View File

@ -0,0 +1,6 @@
//// [FunctionExpression1_es6.ts]
var v = function * () { }
//// [FunctionExpression1_es6.js]
var v = function () {
};

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/es6/functionExpressions/FunctionExpression1_es6.ts ===
var v = function * () { }
>v : () => void
>function * () { } : () => void

View File

@ -0,0 +1,6 @@
//// [FunctionExpression2_es6.ts]
var v = function * foo() { }
//// [FunctionExpression2_es6.js]
var v = function foo() {
};

View File

@ -0,0 +1,6 @@
=== tests/cases/conformance/es6/functionExpressions/FunctionExpression2_es6.ts ===
var v = function * foo() { }
>v : () => void
>function * foo() { } : () => void
>foo : () => void

View File

@ -0,0 +1,6 @@
//// [FunctionPropertyAssignments1_es6.ts]
var v = { *foo() { } }
//// [FunctionPropertyAssignments1_es6.js]
var v = { foo: function () {
} };

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments1_es6.ts ===
var v = { *foo() { } }
>v : { foo: () => void; }
>{ *foo() { } } : { foo: () => void; }
>foo : () => void
>*foo() { } : () => void

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments2_es6.ts(1,12): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments2_es6.ts (1 errors) ====
var v = { *() { } }
~
!!! error TS1003: Identifier expected.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments3_es6.ts(1,12): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments3_es6.ts (1 errors) ====
var v = { *{ } }
~
!!! error TS1003: Identifier expected.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments4_es6.ts(1,13): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments4_es6.ts (1 errors) ====
var v = { * }
~
!!! error TS1003: Identifier expected.

View File

@ -0,0 +1,16 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,12): error TS1003: Identifier expected.
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,22): error TS1005: ',' expected.
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,26): error TS1128: Declaration or statement expected.
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,13): error TS2304: Cannot find name 'foo'.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts (4 errors) ====
var v = { *[foo()]() { } }
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ',' expected.
~
!!! error TS1128: Declaration or statement expected.
~~~
!!! error TS2304: Cannot find name 'foo'.

View File

@ -0,0 +1,7 @@
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments6_es6.ts(1,12): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments6_es6.ts (1 errors) ====
var v = { *<T>() { } }
~
!!! error TS1003: Identifier expected.

View File

@ -0,0 +1,13 @@
//// [MemberFunctionDeclaration1_es6.ts]
class C {
*foo() { }
}
//// [MemberFunctionDeclaration1_es6.js]
var C = (function () {
function C() {
}
C.prototype.foo = function () {
};
return C;
})();

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration1_es6.ts ===
class C {
>C : C
*foo() { }
>foo : () => void
}

View File

@ -0,0 +1,13 @@
//// [MemberFunctionDeclaration2_es6.ts]
class C {
public * foo() { }
}
//// [MemberFunctionDeclaration2_es6.js]
var C = (function () {
function C() {
}
C.prototype.foo = function () {
};
return C;
})();

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration2_es6.ts ===
class C {
>C : C
public * foo() { }
>foo : () => void
}

View File

@ -0,0 +1,18 @@
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration3_es6.ts(2,5): error TS1003: Identifier expected.
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration3_es6.ts(2,10): error TS1005: ';' expected.
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration3_es6.ts(2,13): error TS1005: '=>' expected.
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration3_es6.ts(3,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration3_es6.ts (4 errors) ====
class C {
*[foo]() { }
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: ';' expected.
~
!!! error TS1005: '=>' expected.
}
~
!!! error TS1128: Declaration or statement expected.

View File

@ -0,0 +1,9 @@
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration4_es6.ts(2,5): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration4_es6.ts (1 errors) ====
class C {
*() { }
~
!!! error TS1003: Identifier expected.
}

View File

@ -0,0 +1,9 @@
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration5_es6.ts(3,1): error TS1003: Identifier expected.
==== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration5_es6.ts (1 errors) ====
class C {
*
}
~
!!! error TS1003: Identifier expected.

View File

@ -0,0 +1,12 @@
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration6_es6.ts(3,1): error TS1005: '(' expected.
tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration6_es6.ts(2,5): error TS2391: Function implementation is missing or not immediately following the declaration.
==== tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration6_es6.ts (2 errors) ====
class C {
*foo
~~~
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
}
~
!!! error TS1005: '(' expected.

Some files were not shown because too many files have changed in this diff Show More