Merge branch 'master' into taggedSigHelp

Conflicts:
	src/services/signatureHelp.ts
This commit is contained in:
Daniel Rosenwasser
2014-11-24 16:34:00 -08:00
442 changed files with 12259 additions and 7843 deletions
+5 -5
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 {
+102 -68
View File
@@ -75,43 +75,44 @@ module ts {
var checker: TypeChecker = {
getProgram: () => program,
getDiagnostics: getDiagnostics,
getGlobalDiagnostics: getGlobalDiagnostics,
getNodeCount: () => sum(program.getSourceFiles(), "nodeCount"),
getIdentifierCount: () => sum(program.getSourceFiles(), "identifierCount"),
getSymbolCount: () => sum(program.getSourceFiles(), "symbolCount"),
getTypeCount: () => typeCount,
checkProgram: checkProgram,
emitFiles: invokeEmitter,
getParentOfSymbol: getParentOfSymbol,
getNarrowedTypeOfSymbol: getNarrowedTypeOfSymbol,
getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
getPropertiesOfType: getPropertiesOfType,
getPropertyOfType: getPropertyOfType,
getSignaturesOfType: getSignaturesOfType,
getIndexTypeOfType: getIndexTypeOfType,
getReturnTypeOfSignature: getReturnTypeOfSignature,
getSymbolsInScope: getSymbolsInScope,
getSymbolInfo: getSymbolInfo,
getShorthandAssignmentValueSymbol: getShorthandAssignmentValueSymbol,
getTypeOfNode: getTypeOfNode,
typeToString: typeToString,
getSymbolDisplayBuilder: getSymbolDisplayBuilder,
symbolToString: symbolToString,
getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
getRootSymbols: getRootSymbols,
getContextualType: getContextualType,
getFullyQualifiedName: getFullyQualifiedName,
getResolvedSignature: getResolvedSignature,
getEnumMemberValue: getEnumMemberValue,
isValidPropertyAccess: isValidPropertyAccess,
getSignatureFromDeclaration: getSignatureFromDeclaration,
isImplementationOfOverload: isImplementationOfOverload,
getAliasedSymbol: resolveImport,
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
hasEarlyErrors: hasEarlyErrors,
isEmitBlocked: isEmitBlocked
getDiagnostics,
getDeclarationDiagnostics,
getGlobalDiagnostics,
checkProgram,
invokeEmitter,
getParentOfSymbol,
getNarrowedTypeOfSymbol,
getDeclaredTypeOfSymbol,
getPropertiesOfType,
getPropertyOfType,
getSignaturesOfType,
getIndexTypeOfType,
getReturnTypeOfSignature,
getSymbolsInScope,
getSymbolInfo,
getShorthandAssignmentValueSymbol,
getTypeOfNode,
typeToString,
getSymbolDisplayBuilder,
symbolToString,
getAugmentedPropertiesOfType,
getRootSymbols,
getContextualType,
getFullyQualifiedName,
getResolvedSignature,
getEnumMemberValue,
isValidPropertyAccess,
getSignatureFromDeclaration,
isImplementationOfOverload,
getAliasedSymbol: resolveImport,
hasEarlyErrors,
isEmitBlocked,
};
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");
@@ -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: 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,26 +9145,30 @@ module ts {
getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags);
}
function invokeEmitter(targetSourceFile?: SourceFile) {
var resolver: EmitResolver = {
function createResolver(): EmitResolver {
return {
getProgram: () => program,
getLocalNameOfContainer: getLocalNameOfContainer,
getExpressionNamePrefix: getExpressionNamePrefix,
getExportAssignmentName: getExportAssignmentName,
isReferencedImportDeclaration: isReferencedImportDeclaration,
getNodeCheckFlags: getNodeCheckFlags,
getEnumMemberValue: getEnumMemberValue,
isTopLevelValueImportWithEntityName: isTopLevelValueImportWithEntityName,
hasSemanticErrors: hasSemanticErrors,
isEmitBlocked: isEmitBlocked,
isDeclarationVisible: isDeclarationVisible,
isImplementationOfOverload: isImplementationOfOverload,
writeTypeAtLocation: writeTypeAtLocation,
writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration,
isSymbolAccessible: isSymbolAccessible,
isImportDeclarationEntityNameReferenceDeclarationVisibile: isImportDeclarationEntityNameReferenceDeclarationVisibile,
getConstantValue: getConstantValue,
getLocalNameOfContainer,
getExpressionNamePrefix,
getExportAssignmentName,
isReferencedImportDeclaration,
getNodeCheckFlags,
getEnumMemberValue,
isTopLevelValueImportWithEntityName,
hasSemanticErrors,
isEmitBlocked,
isDeclarationVisible,
isImplementationOfOverload,
writeTypeAtLocation,
writeReturnTypeOfSignatureDeclaration,
isSymbolAccessible,
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 => {
+3 -3
View File
@@ -153,9 +153,9 @@ module ts {
parseStrings(commandLine);
return {
options: options,
filenames: filenames,
errors: errors
options,
filenames,
errors
};
function parseStrings(args: string[]) {
+13 -9
View File
@@ -258,9 +258,9 @@ module ts {
}
return {
file: file,
start: start,
length: length,
file,
start,
length,
messageText: text,
category: message.category,
@@ -335,12 +335,12 @@ module ts {
}
return {
file: file,
start: start,
length: length,
code: code,
category: category,
messageText: messageText
file,
start,
length,
code,
category,
messageText
};
}
@@ -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);
@@ -124,7 +124,7 @@ 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." },
A_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "A 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." },
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 +275,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 +342,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 },
+2 -55
View File
@@ -487,10 +487,9 @@
"category": "Error",
"code": 1161
},
"A object member cannot be declared optional.": {
"An object member cannot be declared optional.": {
"category": "Error",
"code": 1160
"code": 1162
},
"Duplicate identifier '{0}'.": {
@@ -1098,78 +1097,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 +1137,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 +1365,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
+1489 -1283
View File
File diff suppressed because it is too large Load Diff
+1519 -1253
View File
File diff suppressed because it is too large Load Diff
+9 -9
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
@@ -1167,13 +1167,13 @@ module ts {
hasPrecedingLineBreak: () => precedingLineBreak,
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
reScanGreaterToken: reScanGreaterToken,
reScanSlashToken: reScanSlashToken,
reScanTemplateToken: reScanTemplateToken,
scan: scan,
setText: setText,
setTextPos: setTextPos,
tryScan: tryScan,
reScanGreaterToken,
reScanSlashToken,
reScanTemplateToken,
scan,
setText,
setTextPos,
tryScan,
};
}
}
+5 -5
View File
@@ -99,14 +99,14 @@ var sys: System = (function () {
}
return {
args: args,
args,
newLine: "\r\n",
useCaseSensitiveFileNames: false,
write(s: string): void {
WScript.StdOut.Write(s);
},
readFile: readFile,
writeFile: writeFile,
readFile,
writeFile,
resolvePath(path: string): string {
return fso.GetAbsolutePathName(path);
},
@@ -191,8 +191,8 @@ var sys: System = (function () {
// 1 is a standard descriptor for stdout
_fs.writeSync(1, s);
},
readFile: readFile,
writeFile: writeFile,
readFile,
writeFile,
watchFile: (fileName, callback) => {
// watchFile polls a file every 250ms, picking up file notifications.
_fs.watchFile(fileName, { persistent: true, interval: 250 }, fileChanged);
+6 -6
View File
@@ -192,12 +192,12 @@ module ts {
}
return {
getSourceFile: getSourceFile,
getSourceFile,
getDefaultLibFilename: () => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), "lib.d.ts"),
writeFile: writeFile,
writeFile,
getCurrentDirectory: () => currentDirectory || (currentDirectory = sys.getCurrentDirectory()),
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
getCanonicalFileName: getCanonicalFileName,
getCanonicalFileName,
getNewLine: () => sys.newLine
};
}
@@ -367,8 +367,8 @@ module ts {
}
else {
var emitStart = new Date().getTime();
var emitOutput = checker.emitFiles();
var emitErrors = emitOutput.errors;
var emitOutput = checker.invokeEmitter();
var emitErrors = emitOutput.diagnostics;
exitStatus = emitOutput.emitResultStatus;
var reportStart = new Date().getTime();
errors = concatenate(errors, emitErrors);
@@ -394,7 +394,7 @@ module ts {
reportTimeStatistic("Total time", reportStart - parseStart);
}
return { program: program, exitStatus: exitStatus }
return { program, exitStatus };
}
function printVersion() {
+51 -23
View File
@@ -256,19 +256,24 @@ 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
// 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.
ParsedInStrictMode = 0x00002000,
OctalLiteral = 0x00004000,
Modifier = Export | Ambient | Public | Private | Protected | Static,
AccessibilityModifier = Public | Private | Protected,
@@ -284,12 +289,17 @@ module ts {
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 +331,9 @@ module ts {
export interface TypeParameterDeclaration extends Declaration {
name: Identifier;
constraint?: TypeNode;
// For error recovery purposes.
expression?: Expression;
}
export interface SignatureDeclaration extends Declaration, ParsedSignature { }
@@ -535,7 +548,7 @@ module ts {
}
export interface ForInStatement extends IterationStatement {
declaration?: VariableDeclaration;
declarations?: NodeArray<VariableDeclaration>;
variable?: Expression;
expression: Expression;
}
@@ -580,6 +593,7 @@ module ts {
export interface CatchBlock extends Block {
variable: Identifier;
type?: TypeNode;
}
export interface ClassDeclaration extends Declaration {
@@ -644,8 +658,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;
@@ -701,20 +724,21 @@ module ts {
export interface EmitResult {
emitResultStatus: EmitReturnStatus;
errors: Diagnostic[];
diagnostics: Diagnostic[];
sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
}
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;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
invokeEmitter(targetSourceFile?: SourceFile): EmitResult;
getParentOfSymbol(symbol: Symbol): Symbol;
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
@@ -738,7 +762,7 @@ module ts {
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 +829,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 +855,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;
+12 -39
View File
@@ -749,29 +749,6 @@ module FourSlash {
}
}
public verifyImplementorsCountIs(count: number, localFilesOnly: boolean = true) {
var implementors = this.getImplementorsAtCaret();
var implementorsCount = 0;
if (localFilesOnly) {
var localFiles = this.testData.files.map<string>(file => file.fileName);
// Count only the references in local files. Filter the ones in lib and other files.
implementors.forEach((entry) => {
if (localFiles.some((filename) => filename === entry.fileName)) {
++implementorsCount;
}
});
}
else {
implementorsCount = implementors.length;
}
if (implementorsCount !== count) {
var condition = localFilesOnly ? "excluding libs" : "including libs";
this.raiseError("Expected implementors count (" + condition + ") to be " + count + ", but is actually " + implementors.length);
}
}
private getMemberListAtCaret() {
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, true);
}
@@ -788,10 +765,6 @@ module FourSlash {
return this.languageService.getReferencesAtPosition(this.activeFile.fileName, this.currentCaretPosition);
}
private getImplementorsAtCaret() {
return this.languageService.getImplementorsAtPosition(this.activeFile.fileName, this.currentCaretPosition);
}
private assertionMessage(name: string, actualValue: any, expectedValue: any) {
return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue;
}
@@ -2250,7 +2223,7 @@ module FourSlash {
if (errs.length > 0) {
throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n'));
}
checker.emitFiles();
checker.invokeEmitter();
result = result || ''; // Might have an empty fourslash file
// Compile and execute the test
@@ -2284,7 +2257,7 @@ module FourSlash {
// List of all the subfiles we've parsed out
var files: FourSlashFile[] = [];
// Global options
var opts: { [s: string]: string; } = {};
var globalOptions: { [s: string]: string; } = {};
// Marker positions
// Split up the input file by line
@@ -2292,7 +2265,7 @@ module FourSlash {
// we have to string-based splitting instead and try to figure out the delimiting chars
var lines = contents.split('\n');
var markerMap: MarkerMap = {};
var markerPositions: MarkerMap = {};
var markers: Marker[] = [];
var ranges: Range[] = [];
@@ -2333,7 +2306,7 @@ module FourSlash {
} else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(testOptMetadataNames.filename)) {
// Found an @Filename directive, if this is not the first then create a new subfile
if (currentFileContent) {
var file = parseFileContent(currentFileContent, currentFileName, markerMap, markers, ranges);
var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
file.fileOptions = currentFileOptions;
// Store result file
@@ -2353,10 +2326,10 @@ module FourSlash {
}
} else {
// Check if the match is already existed in the global options
if (opts[match[1]] !== undefined) {
if (globalOptions[match[1]] !== undefined) {
throw new Error("Global Option : '" + match[1] + "' is already existed");
}
opts[match[1]] = match[2];
globalOptions[match[1]] = match[2];
}
}
} else if (line == '' || lineLength === 0) {
@@ -2365,7 +2338,7 @@ module FourSlash {
} else {
// Empty line or code line, terminate current subfile if there is one
if (currentFileContent) {
var file = parseFileContent(currentFileContent, currentFileName, markerMap, markers, ranges);
var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
file.fileOptions = currentFileOptions;
// Store result file
@@ -2380,11 +2353,11 @@ module FourSlash {
}
return {
markerPositions: markerMap,
markers: markers,
globalOptions: opts,
files: files,
ranges: ranges
markerPositions,
markers,
globalOptions,
files,
ranges
};
}
+12 -12
View File
@@ -589,8 +589,8 @@ module Harness {
}
},
getDefaultLibFilename: () => defaultLibFileName,
writeFile: writeFile,
getCanonicalFileName: getCanonicalFileName,
writeFile,
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: ()=> sys.newLine
};
@@ -806,11 +806,11 @@ module Harness {
// only emit if there weren't parse errors
var emitResult: ts.EmitResult;
if (!isEmitBlocked) {
emitResult = checker.emitFiles();
emitResult = checker.invokeEmitter();
}
var errors: HarnessDiagnostic[] = [];
program.getDiagnostics().concat(checker.getDiagnostics()).concat(emitResult ? emitResult.errors : []).forEach(err => {
program.getDiagnostics().concat(checker.getDiagnostics()).concat(emitResult ? emitResult.diagnostics : []).forEach(err => {
// TODO: new compiler formats errors after this point to add . and newlines so we'll just do it manually for now
errors.push(getMinimalDiagnostic(err));
});
@@ -845,7 +845,7 @@ module Harness {
declResult = compileResult;
}, settingsCallback, options);
return { declInputFiles: declInputFiles, declOtherFiles: declOtherFiles, declResult: declResult };
return { declInputFiles, declOtherFiles, declResult };
}
function addDtsFile(file: { unitName: string; content: string }, dtsFiles: { unitName: string; content: string }[]) {
@@ -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);
}
@@ -1169,7 +1169,7 @@ module Harness {
var settings = extractCompilerSettings(code);
// List of all the subfiles we've parsed out
var files: TestUnitData[] = [];
var testUnitData: TestUnitData[] = [];
var lines = Utils.splitContentByNewlines(code);
@@ -1205,7 +1205,7 @@ module Harness {
originalFilePath: fileName,
references: refs
};
files.push(newTestFile);
testUnitData.push(newTestFile);
// Reset local data
currentFileContent = null;
@@ -1230,7 +1230,7 @@ module Harness {
}
// normalize the fileName for the single file case
currentFileName = files.length > 0 ? currentFileName : Path.getFileName(fileName);
currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName);
// EOF, push whatever remains
var newTestFile2 = {
@@ -1240,9 +1240,9 @@ module Harness {
originalFilePath: fileName,
references: refs
};
files.push(newTestFile2);
testUnitData.push(newTestFile2);
return { settings: settings, testUnitData: files };
return { settings, testUnitData };
}
}
@@ -1338,7 +1338,7 @@ module Harness {
actual = actual.replace(/\r\n?/g, '\n');
}
return { expected: expected, actual: actual };
return { expected, actual };
}
function writeComparison(expected: string, actual: string, relativeFilename: string, actualFilename: string, descriptionForDescribe: string) {
+46 -20
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,8 +132,8 @@ class ProjectRunner extends RunnerBase {
if (!errors.length) {
var checker = program.getTypeChecker(/*fullTypeCheck*/ true);
errors = checker.getDiagnostics();
var emitResult = checker.emitFiles();
errors = ts.concatenate(errors, emitResult.errors);
var emitResult = checker.invokeEmitter();
errors = ts.concatenate(errors, emitResult.diagnostics);
sourceMapData = emitResult.sourceMaps;
// Clean up source map data that will be used in baselining
@@ -148,10 +149,10 @@ class ProjectRunner extends RunnerBase {
}
return {
moduleKind: moduleKind,
program: program,
errors: errors,
sourceMapData: sourceMapData
moduleKind,
program,
errors,
sourceMapData
};
function createCompilerOptions(): ts.CompilerOptions {
@@ -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
};
}
@@ -183,10 +185,10 @@ class ProjectRunner extends RunnerBase {
function createCompilerHost(): ts.CompilerHost {
return {
getSourceFile: getSourceFile,
getSourceFile,
getDefaultLibFilename: () => "lib.d.ts",
writeFile: writeFile,
getCurrentDirectory: getCurrentDirectory,
writeFile,
getCurrentDirectory,
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
getNewLine: () => sys.newLine
@@ -201,12 +203,12 @@ class ProjectRunner extends RunnerBase {
var projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile);
return {
moduleKind: moduleKind,
moduleKind,
program: projectCompilerResult.program,
sourceMapData: projectCompilerResult.sourceMapData,
outputFiles: outputFiles,
outputFiles,
errors: projectCompilerResult.errors,
nonSubfolderDiskFiles: nonSubfolderDiskFiles,
nonSubfolderDiskFiles,
};
function getSourceFileText(filename: string): string {
@@ -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);
}
+3 -3
View File
@@ -117,14 +117,14 @@ module RWC {
});
function getHarnessCompilerInputUnit(fileName: string) {
var resolvedPath = ts.normalizeSlashes(sys.resolvePath(fileName));
var unitName = ts.normalizeSlashes(sys.resolvePath(fileName));
try {
var content = sys.readFile(resolvedPath);
var content = sys.readFile(unitName);
}
catch (e) {
// Leave content undefined.
}
return { unitName: resolvedPath, content: content };
return { unitName, content };
}
});
+4 -4
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);
@@ -361,8 +361,8 @@ module ts.formatting {
delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta() + delta);
}
return {
indentation: indentation,
delta: delta
indentation,
delta
}
}
@@ -834,7 +834,7 @@ module ts.formatting {
}
function newTextChange(start: number, len: number, newText: string): TextChange {
return { span: new TextSpan(start, len), newText: newText }
return { span: new TextSpan(start, len), newText }
}
function recordDelete(start: number, len: number) {
+11 -8
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);
@@ -262,12 +265,12 @@ module ts.NavigationBar {
}
return {
text: text,
kind: kind,
kindModifiers: kindModifiers,
spans: spans,
childItems: childItems,
indent: indent,
text,
kind,
kindModifiers,
spans,
childItems,
indent,
bolded: false,
grayed: false
};
+128 -187
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,16 +890,12 @@ 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[];
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[];
getImplementorsAtPosition(fileName: string, position: number): ReferenceEntry[];
getNavigateToItems(searchValue: string): NavigateToItem[];
getNavigationBarItems(fileName: string): NavigationBarItem[];
@@ -909,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
@@ -1176,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 {
@@ -1273,7 +1242,9 @@ module ts {
static alias = "alias";
static constantElement = "constant";
static constElement = "const";
static letElement = "let";
}
export class ScriptElementKindModifier {
@@ -1370,8 +1341,8 @@ module ts {
writeSpace: text => writeKind(text, SymbolDisplayPartKind.space),
writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral),
writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName),
writeSymbol: writeSymbol,
writeLine: writeLine,
writeSymbol,
writeLine,
increaseIndent: () => { indent++; },
decreaseIndent: () => { indent--; },
clear: resetWriter,
@@ -1761,7 +1732,7 @@ module ts {
sourceFiles.sort((x, y) => y.refCount - x.refCount);
return {
bucket: name,
sourceFiles: sourceFiles
sourceFiles
};
});
return JSON.stringify(bucketInfoArray, null, 2);
@@ -1827,10 +1798,10 @@ module ts {
}
return {
acquireDocument: acquireDocument,
updateDocument: updateDocument,
releaseDocument: releaseDocument,
reportStats: reportStats
acquireDocument,
updateDocument,
releaseDocument,
reportStats
};
}
@@ -1893,7 +1864,7 @@ module ts {
processImport();
}
processTripleSlashDirectives();
return { referencedFiles: referencedFiles, importedFiles: importedFiles, isLibFile: isNoDefaultLib };
return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib };
}
/// Helpers
@@ -2094,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() {
@@ -2191,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)];
}
}
}
@@ -2234,7 +2209,7 @@ module ts {
}
// Remember the new sourceFile
sourceFilesByName[filename] = sourceFile;
sourceFilesByName[getCanonicalFileName(filename)] = sourceFile;
}
// Now create a new compiler
@@ -2289,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.emitFiles(targetSourceFile).errors);
writer = savedWriter;
allDiagnostics = allDiagnostics.concat(checker.getDeclarationDiagnostics(targetSourceFile));
}
return allDiagnostics
}
@@ -2497,7 +2468,7 @@ module ts {
host.log("getCompletionsAtPosition: Semantic work: " + (new Date().getTime() - semanticStart));
return {
isMemberCompletion: isMemberCompletion,
isMemberCompletion,
entries: activeCompletionSession.entries
};
@@ -2752,7 +2723,7 @@ module ts {
while (true) {
node = node.parent;
if (!node) {
return node;
return undefined;
}
switch (node.kind) {
case SyntaxKind.SourceFile:
@@ -2801,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;
}
@@ -2859,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;
@@ -2958,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
@@ -3034,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);
@@ -3157,7 +3139,7 @@ module ts {
documentation = symbol.getDocumentationComment();
}
return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind };
return { displayParts, documentation, symbolKind };
function addNewLineIfDisplayPartsExist() {
if (displayParts.length) {
@@ -3258,7 +3240,7 @@ module ts {
kind: symbolKind,
name: symbolName,
containerKind: undefined,
containerName: containerName
containerName
};
}
@@ -3327,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,
@@ -3906,39 +3887,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);
@@ -3967,6 +3965,10 @@ module ts {
for (var i = 0, n = declarations.length; i < n; i++) {
var container = getContainerNode(declarations[i]);
if (!container) {
return undefined;
}
if (scope && scope !== container) {
// Different declarations have different containers, bail out
return undefined;
@@ -4531,8 +4533,8 @@ module ts {
fileName: filename,
textSpan: TextSpan.fromBounds(declaration.getStart(), declaration.getEnd()),
// TODO(jfreeman): What should be the containerName when the container has a computed name?
containerName: container.name ? (<Identifier>container.name).text : "",
containerKind: container.name ? getNodeKind(container) : ""
containerName: container && container.name ? (<Identifier>container.name).text : "",
containerKind: container && container.name ? getNodeKind(container) : ""
});
}
}
@@ -4640,7 +4642,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().emitFiles(targetSourceFile);
var emitFilesResult = getFullTypeCheckChecker().invokeEmitter(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
@@ -4686,10 +4688,13 @@ module ts {
else {
return SemanticMeaning.Namespace;
}
break;
case SyntaxKind.ImportDeclaration:
return SemanticMeaning.Value | SemanticMeaning.Type | SemanticMeaning.Namespace;
// An external module can be a Value
case SyntaxKind.SourceFile:
return SemanticMeaning.Namespace | SemanticMeaning.Value;
}
Debug.fail("Unknown declaration type");
}
@@ -4771,68 +4776,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);
@@ -5421,46 +5364,45 @@ module ts {
return {
canRename: true,
localizedErrorMessage: undefined,
displayName: displayName,
fullDisplayName: fullDisplayName,
kind: kind,
kindModifiers: kindModifiers,
triggerSpan: triggerSpan
displayName,
fullDisplayName,
kind,
kindModifiers,
triggerSpan
};
}
}
return {
dispose: dispose,
cleanupSemanticCache: cleanupSemanticCache,
getSyntacticDiagnostics: getSyntacticDiagnostics,
getSemanticDiagnostics: getSemanticDiagnostics,
getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
getSyntacticClassifications: getSyntacticClassifications,
getSemanticClassifications: getSemanticClassifications,
getCompletionsAtPosition: getCompletionsAtPosition,
getCompletionEntryDetails: getCompletionEntryDetails,
getSignatureHelpItems: getSignatureHelpItems,
getQuickInfoAtPosition: getQuickInfoAtPosition,
getDefinitionAtPosition: getDefinitionAtPosition,
getReferencesAtPosition: getReferencesAtPosition,
getOccurrencesAtPosition: getOccurrencesAtPosition,
getImplementorsAtPosition: (filename, position) => [],
getNameOrDottedNameSpan: getNameOrDottedNameSpan,
getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
getNavigateToItems: getNavigateToItems,
getRenameInfo: getRenameInfo,
findRenameLocations: findRenameLocations,
getNavigationBarItems: getNavigationBarItems,
getOutliningSpans: getOutliningSpans,
getTodoComments: getTodoComments,
getBraceMatchingAtPosition: getBraceMatchingAtPosition,
getIndentationAtPosition: getIndentationAtPosition,
getFormattingEditsForRange: getFormattingEditsForRange,
getFormattingEditsForDocument: getFormattingEditsForDocument,
getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
getEmitOutput: getEmitOutput,
getSignatureAtPosition: getSignatureAtPosition,
dispose,
cleanupSemanticCache,
getSyntacticDiagnostics,
getSemanticDiagnostics,
getCompilerOptionsDiagnostics,
getSyntacticClassifications,
getSemanticClassifications,
getCompletionsAtPosition,
getCompletionEntryDetails,
getSignatureHelpItems,
getQuickInfoAtPosition,
getDefinitionAtPosition,
getReferencesAtPosition,
getOccurrencesAtPosition,
getNameOrDottedNameSpan,
getBreakpointStatementAtPosition,
getNavigateToItems,
getRenameInfo,
findRenameLocations,
getNavigationBarItems,
getOutliningSpans,
getTodoComments,
getBraceMatchingAtPosition,
getIndentationAtPosition,
getFormattingEditsForRange,
getFormattingEditsForDocument,
getFormattingEditsAfterKeystroke,
getEmitOutput,
getSourceFile: getCurrentSourceFile,
};
}
@@ -5520,7 +5462,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;
@@ -5607,7 +5550,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.
@@ -5758,9 +5701,7 @@ module ts {
}
}
return {
getClassificationsForLine: getClassificationsForLine
};
return { getClassificationsForLine };
}
function initializeServices() {
+3 -30
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 } }
@@ -133,12 +130,6 @@ module ts {
*/
getOccurrencesAtPosition(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
*/
getImplementorsAtPosition(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
* { name: string; kind: string; kindModifiers: string; containerName: string; containerKind: string; matchKind: string; fileName: string; textSpan: { start: number; length: number}; } [] = [];
@@ -170,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 {
@@ -615,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
/**
@@ -696,16 +679,6 @@ module ts {
});
}
/// GET IMPLEMENTORS
public getImplementorsAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getImplementorsAtPosition('" + fileName + "', " + position + ")",
() => {
return this.languageService.getImplementorsAtPosition(fileName, position);
});
}
/// COMPLETION LISTS
/**
@@ -821,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++) {
+21 -20
View File
@@ -461,40 +461,41 @@ module ts.SignatureHelp {
var callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeInfoResolver, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined);
var items: SignatureHelpItem[] = map(candidates, candidateSignature => {
var signatureHelpParameters: SignatureHelpParameter[];
var prefixParts: SymbolDisplayPart[] = [];
var suffixParts: SymbolDisplayPart[] = [];
var prefixDisplayParts: SymbolDisplayPart[] = [];
var suffixDisplayParts: SymbolDisplayPart[] = [];
if (callTargetDisplayParts) {
prefixParts.push.apply(prefixParts, callTargetDisplayParts);
prefixDisplayParts.push.apply(prefixDisplayParts, callTargetDisplayParts);
}
if (isTypeParameterList) {
prefixParts.push(punctuationPart(SyntaxKind.LessThanToken));
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
var typeParameters = candidateSignature.typeParameters;
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
suffixParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken));
var parameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation));
suffixParts.push.apply(suffixParts, parameterParts);
suffixDisplayParts.push.apply(suffixDisplayParts, parameterParts);
}
else {
var typeParameterParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation));
prefixParts.push.apply(prefixParts, typeParameterParts);
prefixParts.push(punctuationPart(SyntaxKind.OpenParenToken));
prefixDisplayParts.push.apply(prefixDisplayParts, typeParameterParts);
prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
var parameters = candidateSignature.parameters;
signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
suffixParts.push(punctuationPart(SyntaxKind.CloseParenToken));
suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
}
var returnTypeParts = mapToDisplayParts(writer =>
typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation));
suffixParts.push.apply(suffixParts, returnTypeParts);
suffixDisplayParts.push.apply(suffixDisplayParts, returnTypeParts);
return {
isVariadic: candidateSignature.hasRestParameter,
prefixDisplayParts: prefixParts,
suffixDisplayParts: suffixParts,
prefixDisplayParts,
suffixDisplayParts,
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
parameters: signatureHelpParameters,
documentation: candidateSignature.getDocumentationComment()
@@ -512,11 +513,11 @@ module ts.SignatureHelp {
}
return {
items: items,
applicableSpan: applicableSpan,
selectedItemIndex: selectedItemIndex,
argumentIndex: argumentIndex,
argumentCount: argumentCount
items,
applicableSpan,
selectedItemIndex,
argumentIndex,
argumentCount
};
function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter {
@@ -528,8 +529,8 @@ module ts.SignatureHelp {
return {
name: parameter.name,
documentation: parameter.getDocumentationComment(),
displayParts: displayParts,
isOptional: isOptional
displayParts,
isOptional
};
}
@@ -540,7 +541,7 @@ module ts.SignatureHelp {
return {
name: typeParameter.symbol.name,
documentation: emptyArray,
displayParts: displayParts,
displayParts,
isOptional: false
};
}
+16 -8
View File
@@ -222,7 +222,8 @@ module ts.formatting {
if (node.parent) {
switch (node.parent.kind) {
case SyntaxKind.TypeReference:
if ((<TypeReferenceNode>node.parent).typeArguments) {
if ((<TypeReferenceNode>node.parent).typeArguments &&
rangeContainsStartEnd((<TypeReferenceNode>node.parent).typeArguments, node.getStart(sourceFile), node.getEnd())) {
return (<TypeReferenceNode>node.parent).typeArguments;
}
break;
@@ -236,21 +237,28 @@ module ts.formatting {
case SyntaxKind.Method:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
if ((<SignatureDeclaration>node.parent).typeParameters && node.end < (<SignatureDeclaration>node.parent).typeParameters.end) {
var start = node.getStart(sourceFile);
if ((<SignatureDeclaration>node.parent).typeParameters &&
rangeContainsStartEnd((<SignatureDeclaration>node.parent).typeParameters, start, node.getEnd())) {
return (<SignatureDeclaration>node.parent).typeParameters;
}
return (<SignatureDeclaration>node.parent).parameters;
if (rangeContainsStartEnd((<SignatureDeclaration>node.parent).parameters, start, node.getEnd())) {
return (<SignatureDeclaration>node.parent).parameters;
}
break;
case SyntaxKind.NewExpression:
case SyntaxKind.CallExpression:
if ((<CallExpression>node.parent).typeArguments && node.end < (<CallExpression>node.parent).typeArguments.end) {
var start = node.getStart(sourceFile);
if ((<CallExpression>node.parent).typeArguments &&
rangeContainsStartEnd((<CallExpression>node.parent).typeArguments, start, node.getEnd())) {
return (<CallExpression>node.parent).typeArguments;
}
return (<CallExpression>node.parent).arguments;
if (rangeContainsStartEnd((<CallExpression>node.parent).arguments, start, node.getEnd())) {
return (<CallExpression>node.parent).arguments;
}
break;
}
}
return undefined;
}
+22 -12
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
+1
View File
@@ -592,6 +592,7 @@ module TypeScript.IncrementalParser {
text: text,
fileName: fileName,
languageVersion: languageVersion,
absolutePosition: absolutePosition,
currentNode: currentNode,
currentToken: currentToken,
currentContextualToken: currentContextualToken,
+99 -87
View File
@@ -45,6 +45,9 @@ module TypeScript.Parser {
// but can affect the diagnostics produced while parsing.
languageVersion: ts.ScriptTarget;
// The place in the source text that we're currently pointing at.
absolutePosition(): number;
// The current syntax node the source is pointing at. Only available in incremental settings.
// The source can point at a node if that node doesn't intersect any of the text changes in
// the file, and doesn't contain certain unacceptable constructs. For example, if the node
@@ -541,19 +544,37 @@ module TypeScript.Parser {
return eatToken(SyntaxKind.SemicolonToken);
}
function createMissingToken(expectedKind: SyntaxKind, actual: ISyntaxToken, diagnosticCode?: string): ISyntaxToken {
var diagnostic = getExpectedTokenDiagnostic(expectedKind, actual, diagnosticCode);
function createEmptyToken(kind: SyntaxKind): ISyntaxToken {
// The position of the empty token we're creating is not necessarily the position that
// the parser is at now. This is because we may have seen some existing missing tokens
// before finally deciding we needed a missing token. For example, if you have:
//
// Foo(a, # <eof>
//
// We will need to create a empty token for the missing ")". However, we will have
// skipped the "#" token, and thus will be right after the "#". Because the "#" token
// will actually become *skipped* trivia on the *next* token we see, the close paren
// should not be considered to be after #, and should instead be after the ",".
//
// So, if we have any skipped tokens, then the position of the empty token should be
// the position of the first skipped token we have. Otherwise it's just at the position
// of the parser.
var fullStart = _skippedTokens ? _skippedTokens[0].fullStart() : source.absolutePosition();
return Syntax.emptyToken(kind, fullStart);
}
function createMissingToken(expectedKind: SyntaxKind, actual: ISyntaxToken, diagnosticCode?: string, args?: any[]): ISyntaxToken {
var diagnostic = getExpectedTokenDiagnostic(expectedKind, actual, diagnosticCode, args);
addDiagnostic(diagnostic);
// The missing token will be at the full start of the current token. That way empty tokens
// will always be between real tokens and not inside an actual token.
return Syntax.emptyToken(expectedKind);
return createEmptyToken(expectedKind);
}
function getExpectedTokenDiagnostic(expectedKind: SyntaxKind, actual?: ISyntaxToken, diagnosticCode?: string): Diagnostic {
function getExpectedTokenDiagnostic(expectedKind: SyntaxKind, actual?: ISyntaxToken, diagnosticCode?: string, args?: any[]): Diagnostic {
var token = currentToken();
var args: any[] = undefined;
// If a specialized diagnostic message was provided, just use that.
if (!diagnosticCode) {
// They wanted something specific, just report that that token was missing.
@@ -1190,14 +1211,14 @@ module TypeScript.Parser {
return new GetAccessorSyntax(parseNodeData,
modifiers, consumeToken(getKeyword), parsePropertyName(),
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ false, /*generatorParameter:*/ false),
parseFunctionBlock(/*allowYield:*/ false));
parseFunctionBody(/*isGenerator:*/ false));
}
function parseSetAccessor(modifiers: ISyntaxToken[], setKeyword: ISyntaxToken): SetAccessorSyntax {
return new SetAccessorSyntax(parseNodeData,
modifiers, consumeToken(setKeyword), parsePropertyName(),
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ false, /*generatorParameterContext:*/ false),
parseFunctionBlock(/*allowYield:*/ false));
parseFunctionBody(/*isGenerator:*/ false));
}
function isClassElement(inErrorRecovery: boolean): boolean {
@@ -1326,22 +1347,20 @@ module TypeScript.Parser {
parseModifiers(),
eatToken(SyntaxKind.ConstructorKeyword),
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ false, /*generatorParameterContext:*/ false),
isBlockOrArrow() ? parseFunctionBlock(/*allowYield:*/ false) : eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
parseFunctionBody(/*isGenerator:*/ false));
}
function parseMemberFunctionDeclaration(modifiers: ISyntaxToken[], asteriskToken: ISyntaxToken, propertyName: IPropertyNameSyntax): MemberFunctionDeclarationSyntax {
// Note: if we see an arrow after the close paren, then try to parse out a function
// block anyways. It's likely the user just though '=> expr' was legal anywhere a
// block was legal.
var isGeneratorFunction = asteriskToken !== undefined;
var isGenerator = asteriskToken !== undefined;
return new MemberFunctionDeclarationSyntax(parseNodeData,
modifiers,
asteriskToken,
propertyName,
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ isGeneratorFunction, /*generatorParameterContext:*/ isGeneratorFunction),
isBlockOrArrow()
? parseFunctionBlock(/*yieldContext:*/ isGeneratorFunction)
: eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ isGenerator, /*generatorParameterContext:*/ isGenerator),
parseFunctionBody(isGenerator));
}
function parseMemberVariableDeclaration(modifiers: ISyntaxToken[], propertyName: IPropertyNameSyntax): MemberVariableDeclarationSyntax {
@@ -1382,9 +1401,13 @@ module TypeScript.Parser {
asteriskToken,
eatIdentifierToken(),
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yieldContext:*/ isGenerator, /*generatorParameterContext:*/ isGenerator),
isBlockOrArrow()
? parseFunctionBlock(/*yieldContext:*/ isGenerator)
: eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
parseFunctionBody(isGenerator));
}
function parseFunctionBody(isGenerator: boolean): BlockSyntax | ExpressionBody | ISyntaxToken {
return isBlockOrArrow()
? parseFunctionBlockOrExpressionBody(/*yieldContext:*/ isGenerator)
: eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false);
}
function parseModuleName(): INameSyntax {
@@ -2076,33 +2099,33 @@ module TypeScript.Parser {
parseSyntaxList<IStatementSyntax>(ListParsingState.SwitchClause_Statements));
}
function parseThrowStatementExpression(): IExpressionSyntax {
function parseThrowStatement(throwKeyword: ISyntaxToken): ThrowStatementSyntax {
return new ThrowStatementSyntax(parseNodeData,
consumeToken(throwKeyword), tryParseThrowStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
}
function tryParseThrowStatementExpression(): IExpressionSyntax {
// ThrowStatement[Yield] :
// throw [no LineTerminator here]Expression[In, ?Yield];
// Because of automatic semicolon insertion, we need to report error if this
// throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
// directly as that might consume an expression on the following line.
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false)
? createMissingToken(SyntaxKind.IdentifierName, undefined)
: allowInAnd(parseExpression);
// We just return 'undefined' in that case. The actual error will be reported in the
// grammar walker.
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? undefined : allowInAnd(parseExpression);
}
function parseThrowStatement(throwKeyword: ISyntaxToken): ThrowStatementSyntax {
return new ThrowStatementSyntax(parseNodeData,
consumeToken(throwKeyword), parseThrowStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
function parseReturnStatement(returnKeyword: ISyntaxToken): ReturnStatementSyntax {
return new ReturnStatementSyntax(parseNodeData,
consumeToken(returnKeyword), tryParseReturnStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
}
function tryParseReturnStatementExpression(): IExpressionSyntax {
// ReturnStatement[Yield] :
// return [no LineTerminator here]Expression[In, ?Yield];
return !canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? allowInAnd(parseExpression) : undefined;
}
function parseReturnStatement(returnKeyword: ISyntaxToken): ReturnStatementSyntax {
return new ReturnStatementSyntax(parseNodeData,
consumeToken(returnKeyword), tryParseReturnStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? undefined : allowInAnd(parseExpression);
}
function isExpressionStatement(currentToken: ISyntaxToken): boolean {
@@ -2628,7 +2651,7 @@ module TypeScript.Parser {
return token0;
}
function tryParseMemberExpressionOrHigher(_currentToken: ISyntaxToken, force: boolean, inObjectCreation: boolean): IMemberExpressionSyntax {
function tryParseMemberExpressionOrHigher(_currentToken: ISyntaxToken, force: boolean): IMemberExpressionSyntax {
// Note: to make our lives simpler, we decompose the the NewExpression productions and
// place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
// like so:
@@ -2681,7 +2704,7 @@ module TypeScript.Parser {
return undefined;
}
return parseMemberExpressionRest(expression, inObjectCreation);
return parseMemberExpressionRest(expression);
}
function parseCallExpressionRest(expression: ILeftHandSideExpressionSyntax): ILeftHandSideExpressionSyntax {
@@ -2708,7 +2731,7 @@ module TypeScript.Parser {
continue;
case SyntaxKind.OpenBracketToken:
expression = parseElementAccessExpression(expression, _currentToken, /*inObjectCreation:*/ false);
expression = parseElementAccessExpression(expression, _currentToken);
continue;
case SyntaxKind.DotToken:
@@ -2725,14 +2748,14 @@ module TypeScript.Parser {
}
}
function parseMemberExpressionRest(expression: IMemberExpressionSyntax, inObjectCreation: boolean): IMemberExpressionSyntax {
function parseMemberExpressionRest(expression: IMemberExpressionSyntax): IMemberExpressionSyntax {
while (true) {
var _currentToken = currentToken();
var currentTokenKind = _currentToken.kind;
switch (currentTokenKind) {
case SyntaxKind.OpenBracketToken:
expression = parseElementAccessExpression(expression, _currentToken, inObjectCreation);
expression = parseElementAccessExpression(expression, _currentToken);
continue;
case SyntaxKind.DotToken:
@@ -2786,7 +2809,7 @@ module TypeScript.Parser {
expression = parseSuperExpression(_currentToken);
}
else {
expression = tryParseMemberExpressionOrHigher(_currentToken, force, /*inObjectCreation:*/ false);
expression = tryParseMemberExpressionOrHigher(_currentToken, force);
if (expression === undefined) {
return undefined;
}
@@ -2865,13 +2888,10 @@ module TypeScript.Parser {
// we'll bail out here and give a poor error message when we try to parse this
// as an arithmetic expression.
if (isDot) {
// A parameter list must follow a generic type argument list.
var diagnostic = new Diagnostic(fileName, source.text.lineMap(), start(token0, source.text), width(token0),
DiagnosticCode.A_parameter_list_must_follow_a_generic_type_argument_list_expected, undefined);
addDiagnostic(diagnostic);
return new ArgumentListSyntax(parseNodeData, typeArgumentList,
Syntax.emptyToken(SyntaxKind.OpenParenToken), <any>[], Syntax.emptyToken(SyntaxKind.CloseParenToken));
createMissingToken(SyntaxKind.OpenParenToken, undefined, DiagnosticCode.A_parameter_list_must_follow_a_generic_type_argument_list_expected),
<any>[],
eatToken(SyntaxKind.CloseParenToken));
}
else {
Debug.assert(token0.kind === SyntaxKind.OpenParenToken);
@@ -2919,29 +2939,18 @@ module TypeScript.Parser {
return allowInAnd(force ? parseAssignmentExpressionOrHigher : tryParseAssignmentExpressionOrHigher);
}
function parseElementAccessArgumentExpression(openBracketToken: ISyntaxToken, inObjectCreation: boolean) {
function parseElementAccessArgumentExpression(openBracketToken: ISyntaxToken) {
// MemberExpression[?Yield] [ Expression[In, ?Yield] ]
// It's not uncommon for a user to write: "new Type[]". Check for that common pattern
// and report a better error message.
if (inObjectCreation && currentToken().kind === SyntaxKind.CloseBracketToken) {
var errorStart = start(openBracketToken, source.text);
var errorEnd = fullEnd(currentToken());
var diagnostic = new Diagnostic(fileName, source.text.lineMap(), errorStart, errorEnd - errorStart,
DiagnosticCode.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead, undefined);
addDiagnostic(diagnostic);
return Syntax.emptyToken(SyntaxKind.IdentifierName);
}
else {
return allowInAnd(parseExpression);
}
// For error recovery purposes. Allow a missing expression here. We'll report the
// appropriate message in the grammar checker.
return currentToken().kind === SyntaxKind.CloseBracketToken ? undefined : allowInAnd(parseExpression);
}
function parseElementAccessExpression(expression: ILeftHandSideExpressionSyntax, openBracketToken: ISyntaxToken, inObjectCreation: boolean): ElementAccessExpressionSyntax {
function parseElementAccessExpression(expression: ILeftHandSideExpressionSyntax, openBracketToken: ISyntaxToken): ElementAccessExpressionSyntax {
// Debug.assert(currentToken().kind === SyntaxKind.OpenBracketToken);
return new ElementAccessExpressionSyntax(parseNodeData, expression, consumeToken(openBracketToken),
parseElementAccessArgumentExpression(openBracketToken, inObjectCreation), eatToken(SyntaxKind.CloseBracketToken));
parseElementAccessArgumentExpression(openBracketToken), eatToken(SyntaxKind.CloseBracketToken));
}
function tryParsePrimaryExpression(_currentToken: ISyntaxToken, force: boolean): IPrimaryExpressionSyntax {
@@ -3033,7 +3042,7 @@ module TypeScript.Parser {
asteriskToken,
enterYieldContextAnd(eatOptionalIdentifierToken),
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yield:*/ isGenerator, /*generatorParameter:*/ isGenerator),
parseFunctionBlock(/*yield:*/ isGenerator));
parseFunctionBody(isGenerator));
}
function parseObjectCreationExpression(newKeyword: ISyntaxToken): ObjectCreationExpressionSyntax {
@@ -3047,7 +3056,7 @@ module TypeScript.Parser {
// this decision.
return new ObjectCreationExpressionSyntax(parseNodeData,
consumeToken(newKeyword), tryParseMemberExpressionOrHigher(currentToken(), /*force:*/ true, /*inObjectCreation:*/ true), tryParseArgumentList());
consumeToken(newKeyword), tryParseMemberExpressionOrHigher(currentToken(), /*force:*/ true), tryParseArgumentList());
}
function parseTemplateExpression(startToken: ISyntaxToken): IPrimaryExpressionSyntax {
@@ -3084,9 +3093,7 @@ module TypeScript.Parser {
token = consumeToken(token);
}
else {
var diagnostic = getExpectedTokenDiagnostic(SyntaxKind.CloseBraceToken);
addDiagnostic(diagnostic);
token = Syntax.emptyToken(SyntaxKind.TemplateEndToken);
token = createMissingToken(SyntaxKind.TemplateEndToken, undefined, DiagnosticCode._0_expected, ["{"]);
}
return new TemplateClauseSyntax(parseNodeData, expression, token);
@@ -3176,8 +3183,8 @@ module TypeScript.Parser {
// [lookahead not in {] AssignmentExpression[?In]
// { FunctionBody }
if (isBlock()) {
return parseFunctionBlock(/*allowYield:*/ false);
if (currentToken().kind === SyntaxKind.OpenBraceToken) {
return parseFunctionBlock(/*allowYield:*/ false, /*equalsGreaterThanToken:*/ undefined);
}
// We didn't have a block. However, we may be in an error situation. For example,
@@ -3197,6 +3204,7 @@ module TypeScript.Parser {
// treat this like a block with a missing open brace.
return new BlockSyntax(parseNodeData,
/*equalsGreaterThanToken*/ undefined,
eatToken(SyntaxKind.OpenBraceToken),
parseFunctionBlockStatements(),
eatToken(SyntaxKind.CloseBraceToken));
@@ -3225,8 +3233,9 @@ module TypeScript.Parser {
parseArrowFunctionBody());
}
function isBlock(): boolean {
return currentToken().kind === SyntaxKind.OpenBraceToken;
function isFunctionBlock(): boolean {
var currentTokenKind = currentToken().kind;
return currentTokenKind === SyntaxKind.OpenBraceToken || currentTokenKind === SyntaxKind.EqualsGreaterThanToken;
}
function isBlockOrArrow(): boolean {
@@ -3552,7 +3561,7 @@ module TypeScript.Parser {
asteriskToken,
propertyName,
parseCallSignature(/*requireCompleteTypeParameterList:*/ false, /*yield:*/ isGenerator, /*generatorParameter:*/ isGenerator),
parseFunctionBlock(/*yield:*/ isGenerator));
parseFunctionBody(isGenerator));
}
function parseArrayLiteralExpression(openBracketToken: ISyntaxToken): ArrayLiteralExpressionSyntax {
@@ -3568,34 +3577,37 @@ module TypeScript.Parser {
// a block without an open curly.
var openBraceToken: ISyntaxToken;
return new BlockSyntax(parseNodeData,
tryEatToken(SyntaxKind.EqualsGreaterThanToken),
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
openBraceToken.fullWidth() > 0 ? parseSyntaxList<IStatementSyntax>(ListParsingState.Block_Statements) : [],
eatToken(SyntaxKind.CloseBraceToken));
}
function parseFunctionBlock(_allowYield: boolean): BlockSyntax {
function parseFunctionBlockOrExpressionBody(_allowYield: boolean): BlockSyntax | ExpressionBody {
// If we got an errant => then we want to parse what's coming up without requiring an
// open brace. ItWe do this because it's not uncommon for people to get confused as to
// open brace. We do this because it's not uncommon for people to get confused as to
// where/when they can use an => and we want to have good error recovery here.
var token0 = currentToken();
var hasEqualsGreaterThanToken = token0.kind === SyntaxKind.EqualsGreaterThanToken;
if (hasEqualsGreaterThanToken) {
addDiagnostic(new Diagnostic(fileName, source.text.lineMap(),
start(token0, source.text), width(token0), DiagnosticCode.Unexpected_token_0_expected, [SyntaxFacts.getText(SyntaxKind.OpenBraceToken)]));
// Skip over the => It will get attached to whatever comes next.
skipToken(token0);
var equalsGreaterThanToken = tryEatToken(SyntaxKind.EqualsGreaterThanToken);
if (equalsGreaterThanToken) {
// check if they wrote something like: => expr
// or if it was more like : => statement
if (isExpression(currentToken())) {
return new ExpressionBody(parseNodeData, equalsGreaterThanToken, parseExpression());
}
}
var openBraceToken = eatToken(SyntaxKind.OpenBraceToken);
var statements: IStatementSyntax[];
return parseFunctionBlock(_allowYield, equalsGreaterThanToken);
}
if (hasEqualsGreaterThanToken || openBraceToken.fullWidth() > 0) {
statements = _allowYield ? enterYieldContextAnd(parseFunctionBlockStatements) : exitYieldContextAnd(parseFunctionBlockStatements);
}
return new BlockSyntax(parseNodeData, openBraceToken, statements || [], eatToken(SyntaxKind.CloseBraceToken));
function parseFunctionBlock(_allowYield: boolean, equalsGreaterThanToken: ISyntaxToken): BlockSyntax {
var openBraceToken: ISyntaxToken;
return new BlockSyntax(parseNodeData,
equalsGreaterThanToken,
openBraceToken = eatToken(SyntaxKind.OpenBraceToken),
equalsGreaterThanToken || openBraceToken.fullWidth() > 0
? _allowYield ? enterYieldContextAnd(parseFunctionBlockStatements) : exitYieldContextAnd(parseFunctionBlockStatements)
: [],
eatToken(SyntaxKind.CloseBraceToken));
}
function parseFunctionBlockStatements() {
@@ -4219,7 +4231,7 @@ module TypeScript.Parser {
// consume the '}' just fine. So ASI doesn't apply.
if (allowAutomaticSemicolonInsertion && canEatAutomaticSemicolon(/*allowWithoutNewline:*/ false)) {
var semicolonToken = eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) || Syntax.emptyToken(SyntaxKind.SemicolonToken);
var semicolonToken = eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) || createEmptyToken(SyntaxKind.SemicolonToken);
nodesAndSeparators.push(semicolonToken);
// Debug.assert(items.length % 2 === 0);
continue;
+15 -9
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 {
+1 -1
View File
@@ -435,7 +435,7 @@ module TypeScript {
modifiers: ISyntaxToken[];
propertyName: IPropertyNameSyntax;
callSignature: CallSignatureSyntax;
block: BlockSyntax;
body: BlockSyntax | ExpressionBody | ISyntaxToken;
}
export interface ISwitchClauseSyntax extends ISyntaxNode {
+19 -10
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',
@@ -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;
+1
View File
@@ -268,6 +268,7 @@ module TypeScript {
Parameter,
EnumElement,
TypeAnnotation,
ExpressionBody,
ComputedPropertyName,
ExternalModuleReference,
ModuleNameModuleReference,
@@ -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,
+6 -74
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 ""; }
+80 -7
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;
}
@@ -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;
+10 -4
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);
+6 -6
View File
@@ -66,22 +66,22 @@ module ts {
}
export function findListItemInfo(node: Node): ListItemInfo {
var syntaxList = findContainingList(node);
var list = findContainingList(node);
// It is possible at this point for syntaxList to be undefined, either if
// node.parent had no list child, or if none of its list children contained
// the span of node. If this happens, return undefined. The caller should
// handle this case.
if (!syntaxList) {
if (!list) {
return undefined;
}
var children = syntaxList.getChildren();
var index = indexOf(children, node);
var children = list.getChildren();
var listItemIndex = indexOf(children, node);
return {
listItemIndex: index,
list: syntaxList
listItemIndex,
list
};
}