mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of https://github.com/Microsoft/TypeScript into iteratorSpreadDestructure
This commit is contained in:
+18
-9
@@ -168,7 +168,7 @@ module ts {
|
||||
addDeclarationToSymbol(symbol, node, includes);
|
||||
symbol.parent = parent;
|
||||
|
||||
if (node.kind === SyntaxKind.ClassDeclaration && symbol.exports) {
|
||||
if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && symbol.exports) {
|
||||
// TypeScript 1.0 spec (April 2014): 8.4
|
||||
// Every class automatically contains a static property member named 'prototype',
|
||||
// the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
|
||||
@@ -286,6 +286,7 @@ module ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (node.flags & NodeFlags.Static) {
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
|
||||
@@ -387,23 +388,28 @@ module ts {
|
||||
bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true);
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
switch (blockScopeContainer.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareModuleMember(node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>container)) {
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareModuleMember(node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
}
|
||||
// fall through.
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = {};
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
|
||||
bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
function getDestructuringParameterName(node: Declaration) {
|
||||
@@ -485,11 +491,14 @@ module ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true);
|
||||
break;
|
||||
case SyntaxKind.ClassExpression:
|
||||
bindAnonymousDeclaration(<ClassExpression>node, SymbolFlags.Class, "__class", /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.CatchClause:
|
||||
bindCatchVariableDeclaration(<CatchClause>node);
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false);
|
||||
bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);
|
||||
@@ -584,9 +593,9 @@ module ts {
|
||||
// containing class.
|
||||
if (node.flags & NodeFlags.AccessibilityModifier &&
|
||||
node.parent.kind === SyntaxKind.Constructor &&
|
||||
node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
(node.parent.parent.kind === SyntaxKind.ClassDeclaration || node.parent.parent.kind === SyntaxKind.ClassExpression)) {
|
||||
|
||||
let classDeclaration = <ClassDeclaration>node.parent.parent;
|
||||
let classDeclaration = <ClassLikeDeclaration>node.parent.parent;
|
||||
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
+554
-162
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,12 @@
|
||||
/// <reference path="scanner.ts"/>
|
||||
|
||||
module ts {
|
||||
/* @internal */
|
||||
export var optionDeclarations: CommandLineOption[] = [
|
||||
{
|
||||
name: "charset",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
name: "codepage",
|
||||
type: "number",
|
||||
},
|
||||
{
|
||||
name: "declaration",
|
||||
shortName: "d",
|
||||
@@ -78,10 +75,6 @@ module ts {
|
||||
name: "noLib",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "noLibCheck",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "noResolve",
|
||||
type: "boolean",
|
||||
@@ -117,6 +110,10 @@ module ts {
|
||||
type: "boolean",
|
||||
description: Diagnostics.Do_not_emit_comments_to_output,
|
||||
},
|
||||
{
|
||||
name: "separateCompilation",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "sourceMap",
|
||||
type: "boolean",
|
||||
@@ -140,18 +137,6 @@ module ts {
|
||||
description: Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
|
||||
experimental: true
|
||||
},
|
||||
{
|
||||
name: "preserveNewLines",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Preserve_new_lines_when_emitting_code,
|
||||
experimental: true
|
||||
},
|
||||
{
|
||||
name: "cacheDownlevelForOfLength",
|
||||
type: "boolean",
|
||||
description: "Cache length access when downlevel emitting for-of statements",
|
||||
experimental: true,
|
||||
},
|
||||
{
|
||||
name: "target",
|
||||
shortName: "t",
|
||||
@@ -171,9 +156,15 @@ module ts {
|
||||
shortName: "w",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Watch_input_files,
|
||||
},
|
||||
{
|
||||
name: "emitDecoratorMetadata",
|
||||
type: "boolean",
|
||||
experimental: true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
/* @internal */
|
||||
export function parseCommandLine(commandLine: string[]): ParsedCommandLine {
|
||||
var options: CompilerOptions = {};
|
||||
var fileNames: string[] = [];
|
||||
@@ -283,6 +274,10 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read tsconfig.json file
|
||||
* @param fileName The path to the config file
|
||||
*/
|
||||
export function readConfigFile(fileName: string): any {
|
||||
try {
|
||||
var text = sys.readFile(fileName);
|
||||
@@ -292,6 +287,12 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the contents of a config file (tsconfig.json).
|
||||
* @param json The contents of the config file to parse
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseConfigFile(json: any, basePath?: string): ParsedCommandLine {
|
||||
var errors: Diagnostic[] = [];
|
||||
|
||||
|
||||
@@ -314,12 +314,12 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
|
||||
function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type: TypeNode | EntityName | HeritageClauseElement, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
|
||||
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
|
||||
emitType(type);
|
||||
}
|
||||
|
||||
function emitType(type: TypeNode | StringLiteralExpression | Identifier | QualifiedName) {
|
||||
function emitType(type: TypeNode | StringLiteralExpression | Identifier | QualifiedName | HeritageClauseElement) {
|
||||
switch (type.kind) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -329,6 +329,8 @@ module ts {
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return writeTextOfNode(currentSourceFile, type);
|
||||
case SyntaxKind.HeritageClauseElement:
|
||||
return emitHeritageClauseElement(<HeritageClauseElement>type);
|
||||
case SyntaxKind.TypeReference:
|
||||
return emitTypeReference(<TypeReferenceNode>type);
|
||||
case SyntaxKind.TypeQuery:
|
||||
@@ -350,11 +352,9 @@ module ts {
|
||||
return emitEntityName(<Identifier>type);
|
||||
case SyntaxKind.QualifiedName:
|
||||
return emitEntityName(<QualifiedName>type);
|
||||
default:
|
||||
Debug.fail("Unknown type annotation: " + type.kind);
|
||||
}
|
||||
|
||||
function emitEntityName(entityName: EntityName) {
|
||||
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
|
||||
let visibilityResult = resolver.isEntityNameVisible(entityName,
|
||||
// Aliases can be written asynchronously so use correct enclosing declaration
|
||||
entityName.parent.kind === SyntaxKind.ImportEqualsDeclaration ? entityName.parent : enclosingDeclaration);
|
||||
@@ -362,15 +362,28 @@ module ts {
|
||||
handleSymbolAccessibilityError(visibilityResult);
|
||||
writeEntityName(entityName);
|
||||
|
||||
function writeEntityName(entityName: EntityName) {
|
||||
function writeEntityName(entityName: EntityName | Expression) {
|
||||
if (entityName.kind === SyntaxKind.Identifier) {
|
||||
writeTextOfNode(currentSourceFile, entityName);
|
||||
}
|
||||
else {
|
||||
let qualifiedName = <QualifiedName>entityName;
|
||||
writeEntityName(qualifiedName.left);
|
||||
let left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
|
||||
let right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
|
||||
writeEntityName(left);
|
||||
write(".");
|
||||
writeTextOfNode(currentSourceFile, qualifiedName.right);
|
||||
writeTextOfNode(currentSourceFile, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClauseElement(node: HeritageClauseElement) {
|
||||
if (isSupportedHeritageClauseElement(node)) {
|
||||
Debug.assert(node.expression.kind === SyntaxKind.Identifier || node.expression.kind === SyntaxKind.PropertyAccessExpression);
|
||||
emitEntityName(<Identifier | PropertyAccessExpression>node.expression);
|
||||
if (node.typeArguments) {
|
||||
write("<");
|
||||
emitCommaList(node.typeArguments, emitType);
|
||||
write(">");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,14 +840,16 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: TypeReferenceNode[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(typeReferences: HeritageClauseElement[], isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
}
|
||||
|
||||
function emitTypeOfTypeReference(node: TypeReferenceNode) {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
|
||||
function emitTypeOfTypeReference(node: HeritageClauseElement) {
|
||||
if (isSupportedHeritageClauseElement(node)) {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError);
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
@@ -877,11 +892,11 @@ module ts {
|
||||
let prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
emitTypeParameters(node.typeParameters);
|
||||
let baseTypeNode = getClassBaseTypeNode(node);
|
||||
let baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
||||
}
|
||||
emitHeritageClause(getClassImplementedTypeNodes(node), /*isImplementsList*/ true);
|
||||
emitHeritageClause(getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
write(" {");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
@@ -993,7 +1008,18 @@ module ts {
|
||||
}
|
||||
|
||||
function emitBindingPattern(bindingPattern: BindingPattern) {
|
||||
emitCommaList(bindingPattern.elements, emitBindingElement);
|
||||
// Only select non-omitted expression from the bindingPattern's elements.
|
||||
// We have to do this to avoid emitting trailing commas.
|
||||
// For example:
|
||||
// original: var [, c,,] = [ 2,3,4]
|
||||
// emitted: declare var c: number; // instead of declare var c:number, ;
|
||||
let elements: Node[] = [];
|
||||
for (let element of bindingPattern.elements) {
|
||||
if (element.kind !== SyntaxKind.OmittedExpression){
|
||||
elements.push(element);
|
||||
}
|
||||
}
|
||||
emitCommaList(elements, emitBindingElement);
|
||||
}
|
||||
|
||||
function emitBindingElement(bindingElement: BindingElement) {
|
||||
@@ -1291,7 +1317,10 @@ module ts {
|
||||
write("...");
|
||||
}
|
||||
if (isBindingPattern(node.name)) {
|
||||
write("_" + indexOf((<FunctionLikeDeclaration>node.parent).parameters, node));
|
||||
// For bindingPattern, we can't simply writeTextOfNode from the source file
|
||||
// because we want to omit the initializer and using writeTextOfNode will result in initializer get emitted.
|
||||
// Therefore, we will have to recursively emit each element in the bindingPattern.
|
||||
emitBindingPattern(<BindingPattern>node.name);
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node.name);
|
||||
@@ -1311,41 +1340,46 @@ module ts {
|
||||
}
|
||||
|
||||
function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
let diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||
return diagnosticMessage !== undefined ? {
|
||||
diagnosticMessage,
|
||||
errorNode: node,
|
||||
typeName: node.name
|
||||
} : undefined;
|
||||
}
|
||||
|
||||
function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult: SymbolAccessiblityResult): DiagnosticMessage {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ConstructSignature:
|
||||
// Interfaces cannot have parameter types that cannot be named
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
// Interfaces cannot have parameter types that cannot be named
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
if (node.parent.flags & NodeFlags.Static) {
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
|
||||
}
|
||||
else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||
Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
|
||||
@@ -1353,30 +1387,99 @@ module ts {
|
||||
}
|
||||
else {
|
||||
// Interfaces cannot have parameter types that cannot be named
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
|
||||
return symbolAccesibilityResult.errorModuleName ?
|
||||
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
|
||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
|
||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
|
||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
|
||||
}
|
||||
|
||||
return {
|
||||
diagnosticMessage,
|
||||
errorNode: node,
|
||||
typeName: node.name
|
||||
};
|
||||
}
|
||||
|
||||
function emitBindingPattern(bindingPattern: BindingPattern) {
|
||||
// We have to explicitly emit square bracket and bracket because these tokens are not store inside the node.
|
||||
if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
write("{");
|
||||
emitCommaList(bindingPattern.elements, emitBindingElement);
|
||||
write("}");
|
||||
}
|
||||
else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) {
|
||||
write("[");
|
||||
let elements = bindingPattern.elements;
|
||||
emitCommaList(elements, emitBindingElement);
|
||||
if (elements && elements.hasTrailingComma) {
|
||||
write(", ");
|
||||
}
|
||||
write("]");
|
||||
}
|
||||
}
|
||||
|
||||
function emitBindingElement(bindingElement: BindingElement) {
|
||||
function getBindingElementTypeVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccesibilityResult);
|
||||
return diagnosticMessage !== undefined ? {
|
||||
diagnosticMessage,
|
||||
errorNode: bindingElement,
|
||||
typeName: bindingElement.name
|
||||
} : undefined;
|
||||
}
|
||||
|
||||
if (bindingElement.kind === SyntaxKind.OmittedExpression) {
|
||||
// If bindingElement is an omittedExpression (i.e. containing elision),
|
||||
// we will emit blank space (although this may differ from users' original code,
|
||||
// it allows emitSeparatedList to write separator appropriately)
|
||||
// Example:
|
||||
// original: function foo([, x, ,]) {}
|
||||
// emit : function foo([ , x, , ]) {}
|
||||
write(" ");
|
||||
}
|
||||
else if (bindingElement.kind === SyntaxKind.BindingElement) {
|
||||
if (bindingElement.propertyName) {
|
||||
// bindingElement has propertyName property in the following case:
|
||||
// { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y"
|
||||
// We have to explicitly emit the propertyName before descending into its binding elements.
|
||||
// Example:
|
||||
// original: function foo({y: [a,b,c]}) {}
|
||||
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
|
||||
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
|
||||
write(": ");
|
||||
|
||||
// If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
|
||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||
}
|
||||
else if (bindingElement.name) {
|
||||
if (isBindingPattern(bindingElement.name)) {
|
||||
// If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
|
||||
// In the case of rest element, we will omit rest element.
|
||||
// Example:
|
||||
// original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {}
|
||||
// emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void;
|
||||
// original with rest: function foo([a, ...c]) {}
|
||||
// emit : declare function foo([a, ...c]): void;
|
||||
emitBindingPattern(<BindingPattern>bindingElement.name);
|
||||
}
|
||||
else {
|
||||
Debug.assert(bindingElement.name.kind === SyntaxKind.Identifier);
|
||||
// If the node is just an identifier, we will simply emit the text associated with the node's name
|
||||
// Example:
|
||||
// original: function foo({y = 10, x}) {}
|
||||
// emit : declare function foo({y, x}: {number, any}): void;
|
||||
if (bindingElement.dotDotDotToken) {
|
||||
write("...");
|
||||
}
|
||||
writeTextOfNode(currentSourceFile, bindingElement.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNode(node: Node) {
|
||||
|
||||
@@ -165,6 +165,10 @@ module ts {
|
||||
Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." },
|
||||
Decorators_are_not_valid_here: { code: 1206, category: DiagnosticCategory.Error, key: "Decorators are not valid here." },
|
||||
Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." },
|
||||
Cannot_compile_non_external_modules_when_the_separateCompilation_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile non-external modules when the '--separateCompilation' flag is provided." },
|
||||
Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." },
|
||||
Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." },
|
||||
A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" },
|
||||
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." },
|
||||
@@ -351,6 +355,8 @@ module ts {
|
||||
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 2496, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },
|
||||
External_module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct: { code: 2497, category: DiagnosticCategory.Error, key: "External module '{0}' resolves to a non-module entity and cannot be imported using this construct." },
|
||||
External_module_0_uses_export_and_cannot_be_used_with_export_Asterisk: { code: 2498, category: DiagnosticCategory.Error, key: "External module '{0}' uses 'export =' and cannot be used with 'export *'." },
|
||||
An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: { code: 2499, category: DiagnosticCategory.Error, key: "An interface can only extend an identifier/qualified-name with optional type arguments." },
|
||||
A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: { code: 2500, category: DiagnosticCategory.Error, key: "A class can only implement an identifier/qualified-name with optional type arguments." },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
|
||||
@@ -434,6 +440,11 @@ module ts {
|
||||
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
|
||||
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
|
||||
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
|
||||
Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." },
|
||||
Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." },
|
||||
Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." },
|
||||
Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." },
|
||||
Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." },
|
||||
Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." },
|
||||
Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." },
|
||||
Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." },
|
||||
@@ -496,7 +507,26 @@ module ts {
|
||||
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
|
||||
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
|
||||
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
|
||||
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
|
||||
export_can_only_be_used_in_a_ts_file: { code: 8003, category: DiagnosticCategory.Error, key: "'export=' can only be used in a .ts file." },
|
||||
type_parameter_declarations_can_only_be_used_in_a_ts_file: { code: 8004, category: DiagnosticCategory.Error, key: "'type parameter declarations' can only be used in a .ts file." },
|
||||
implements_clauses_can_only_be_used_in_a_ts_file: { code: 8005, category: DiagnosticCategory.Error, key: "'implements clauses' can only be used in a .ts file." },
|
||||
interface_declarations_can_only_be_used_in_a_ts_file: { code: 8006, category: DiagnosticCategory.Error, key: "'interface declarations' can only be used in a .ts file." },
|
||||
module_declarations_can_only_be_used_in_a_ts_file: { code: 8007, category: DiagnosticCategory.Error, key: "'module declarations' can only be used in a .ts file." },
|
||||
type_aliases_can_only_be_used_in_a_ts_file: { code: 8008, category: DiagnosticCategory.Error, key: "'type aliases' can only be used in a .ts file." },
|
||||
_0_can_only_be_used_in_a_ts_file: { code: 8009, category: DiagnosticCategory.Error, key: "'{0}' can only be used in a .ts file." },
|
||||
types_can_only_be_used_in_a_ts_file: { code: 8010, category: DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." },
|
||||
type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." },
|
||||
parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." },
|
||||
can_only_be_used_in_a_ts_file: { code: 8013, category: DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." },
|
||||
property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." },
|
||||
enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." },
|
||||
type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." },
|
||||
decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." },
|
||||
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
|
||||
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
|
||||
Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
|
||||
class_expressions_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'class' expressions are not currently supported." },
|
||||
class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." },
|
||||
};
|
||||
}
|
||||
@@ -651,7 +651,22 @@
|
||||
"category": "Error",
|
||||
"code": 1207
|
||||
},
|
||||
|
||||
"Cannot compile non-external modules when the '--separateCompilation' flag is provided.": {
|
||||
"category": "Error",
|
||||
"code": 1208
|
||||
},
|
||||
"Ambient const enums are not allowed when the '--separateCompilation' flag is provided.": {
|
||||
"category": "Error",
|
||||
"code": 1209
|
||||
},
|
||||
"Invalid use of '{0}'. Class definitions are automatically in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1210
|
||||
},
|
||||
"A class declaration without the 'default' modifier must have a name": {
|
||||
"category": "Error",
|
||||
"code": 1211
|
||||
},
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2300
|
||||
@@ -1396,6 +1411,14 @@
|
||||
"category": "Error",
|
||||
"code": 2498
|
||||
},
|
||||
"An interface can only extend an identifier/qualified-name with optional type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2499
|
||||
},
|
||||
"A class can only implement an identifier/qualified-name with optional type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2500
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -1729,6 +1752,26 @@
|
||||
"category": "Error",
|
||||
"code": 5042
|
||||
},
|
||||
"Option 'sourceMap' cannot be specified with option 'separateCompilation'.": {
|
||||
"category": "Error",
|
||||
"code": 5043
|
||||
},
|
||||
"Option 'declaration' cannot be specified with option 'separateCompilation'.": {
|
||||
"category": "Error",
|
||||
"code": 5044
|
||||
},
|
||||
"Option 'noEmitOnError' cannot be specified with option 'separateCompilation'.": {
|
||||
"category": "Error",
|
||||
"code": 5045
|
||||
},
|
||||
"Option 'out' cannot be specified with option 'separateCompilation'.": {
|
||||
"category": "Error",
|
||||
"code": 5046
|
||||
},
|
||||
"Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": {
|
||||
"category": "Error",
|
||||
"code": 5047
|
||||
},
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
"code": 6001
|
||||
@@ -1978,6 +2021,71 @@
|
||||
"category": "Error",
|
||||
"code": 8001
|
||||
},
|
||||
"'import ... =' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8002
|
||||
},
|
||||
"'export=' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8003
|
||||
},
|
||||
"'type parameter declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8004
|
||||
},
|
||||
"'implements clauses' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8005
|
||||
},
|
||||
"'interface declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8006
|
||||
},
|
||||
"'module declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8007
|
||||
},
|
||||
"'type aliases' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8008
|
||||
},
|
||||
"'{0}' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8009
|
||||
},
|
||||
"'types' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8010
|
||||
},
|
||||
"'type arguments' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8011
|
||||
},
|
||||
"'parameter modifiers' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8012
|
||||
},
|
||||
"'?' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8013
|
||||
},
|
||||
"'property declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8014
|
||||
},
|
||||
"'enum declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8015
|
||||
},
|
||||
"'type assertion expressions' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8016
|
||||
},
|
||||
"'decorators' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
},
|
||||
|
||||
"'yield' expressions are not currently supported.": {
|
||||
"category": "Error",
|
||||
"code": 9000
|
||||
@@ -1985,5 +2093,17 @@
|
||||
"Generators are not currently supported.": {
|
||||
"category": "Error",
|
||||
"code": 9001
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
},
|
||||
"'class' expressions are not currently supported.": {
|
||||
"category": "Error",
|
||||
"code": 9003
|
||||
},
|
||||
"'class' declarations are only supported directly inside a module or as a top level declaration.": {
|
||||
"category": "Error",
|
||||
"code": 9004
|
||||
}
|
||||
}
|
||||
|
||||
+815
-714
File diff suppressed because it is too large
Load Diff
+152
-47
@@ -237,12 +237,13 @@ module ts {
|
||||
case SyntaxKind.Decorator:
|
||||
return visitNode(cbNode, (<Decorator>node).expression);
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ClassDeclaration>node).name) ||
|
||||
visitNodes(cbNodes, (<ClassDeclaration>node).typeParameters) ||
|
||||
visitNodes(cbNodes, (<ClassDeclaration>node).heritageClauses) ||
|
||||
visitNodes(cbNodes, (<ClassDeclaration>node).members);
|
||||
visitNode(cbNode, (<ClassLikeDeclaration>node).name) ||
|
||||
visitNodes(cbNodes, (<ClassLikeDeclaration>node).typeParameters) ||
|
||||
visitNodes(cbNodes, (<ClassLikeDeclaration>node).heritageClauses) ||
|
||||
visitNodes(cbNodes, (<ClassLikeDeclaration>node).members);
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
visitNodes(cbNodes, node.modifiers) ||
|
||||
@@ -308,6 +309,9 @@ module ts {
|
||||
return visitNode(cbNode, (<ComputedPropertyName>node).expression);
|
||||
case SyntaxKind.HeritageClause:
|
||||
return visitNodes(cbNodes, (<HeritageClause>node).types);
|
||||
case SyntaxKind.HeritageClauseElement:
|
||||
return visitNode(cbNode, (<HeritageClauseElement>node).expression) ||
|
||||
visitNodes(cbNodes, (<HeritageClauseElement>node).typeArguments);
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return visitNode(cbNode, (<ExternalModuleReference>node).expression);
|
||||
case SyntaxKind.MissingDeclaration:
|
||||
@@ -324,7 +328,7 @@ module ts {
|
||||
TypeMembers, // Members in interface or type literal
|
||||
ClassMembers, // Members in class declaration
|
||||
EnumMembers, // Members in enum declaration
|
||||
TypeReferences, // Type references in extends or implements clause
|
||||
HeritageClauseElement, // Elements in a heritage clause
|
||||
VariableDeclarations, // Variable declarations in variable statement
|
||||
ObjectBindingElements, // Binding elements in object binding list
|
||||
ArrayBindingElements, // Binding elements in array binding list
|
||||
@@ -356,7 +360,7 @@ module ts {
|
||||
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
|
||||
case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
|
||||
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
|
||||
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
|
||||
case ParsingContext.HeritageClauseElement: return Diagnostics.Expression_expected;
|
||||
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected;
|
||||
case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected;
|
||||
case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected;
|
||||
@@ -824,7 +828,7 @@ module ts {
|
||||
// to reuse are already at the appropriate position in the new text. That way when we
|
||||
// reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
|
||||
// it very easy to determine if we can reuse a node. If the node's position is at where
|
||||
// we are in the text, then we can reuse it. Otherwise we can't. If hte node's position
|
||||
// we are in the text, then we can reuse it. Otherwise we can't. If the node's position
|
||||
// is ahead of us, then we'll need to rescan tokens. If the node's position is behind
|
||||
// us, then we'll need to skip it or crumble it as appropriate
|
||||
//
|
||||
@@ -1029,7 +1033,7 @@ module ts {
|
||||
// that some tokens that would be considered identifiers may be considered keywords.
|
||||
//
|
||||
// When adding more parser context flags, consider which is the more common case that the
|
||||
// flag will be in. This should be hte 'false' state for that flag. The reason for this is
|
||||
// flag will be in. This should be the 'false' state for that flag. The reason for this is
|
||||
// that we don't store data in our nodes unless the value is in the *non-default* state. So,
|
||||
// for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for
|
||||
// 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost
|
||||
@@ -1040,7 +1044,7 @@ module ts {
|
||||
//
|
||||
// An important thing about these context concepts. By default they are effectively inherited
|
||||
// while parsing through every grammar production. i.e. if you don't change them, then when
|
||||
// you parse a sub-production, it will have the same context values as hte parent production.
|
||||
// you parse a sub-production, it will have the same context values as the parent production.
|
||||
// This is great most of the time. After all, consider all the 'expression' grammar productions
|
||||
// and how nearly all of them pass along the 'in' and 'yield' context values:
|
||||
//
|
||||
@@ -1605,7 +1609,11 @@ module ts {
|
||||
case ParsingContext.TypeMembers:
|
||||
return isStartOfTypeMember();
|
||||
case ParsingContext.ClassMembers:
|
||||
return lookAhead(isClassMemberStart);
|
||||
// We allow semicolons as class elements (as specified by ES6) as long as we're
|
||||
// not in error recovery. If we're in error recovery, we don't want an errant
|
||||
// semicolon to be treated as a class member (since they're almost always used
|
||||
// for statements.
|
||||
return lookAhead(isClassMemberStart) || (token === SyntaxKind.SemicolonToken && !inErrorRecovery);
|
||||
case ParsingContext.EnumMembers:
|
||||
// Include open bracket computed properties. This technically also lets in indexers,
|
||||
// which would be a candidate for improved error reporting.
|
||||
@@ -1614,10 +1622,22 @@ module ts {
|
||||
return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName();
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
return isLiteralPropertyName();
|
||||
case ParsingContext.TypeReferences:
|
||||
// We want to make sure that the "extends" in "extends foo" or the "implements" in
|
||||
// "implements foo" is not considered a type name.
|
||||
return isIdentifier() && !isNotHeritageClauseTypeName();
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
// If we see { } then only consume it as an expression if it is followed by , or {
|
||||
// That way we won't consume the body of a class in its heritage clause.
|
||||
if (token === SyntaxKind.OpenBraceToken) {
|
||||
return lookAhead(isValidHeritageClauseObjectLiteral);
|
||||
}
|
||||
|
||||
if (!inErrorRecovery) {
|
||||
return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
|
||||
}
|
||||
else {
|
||||
// If we're in error recovery we tighten up what we're willing to match.
|
||||
// That way we don't treat something like "this" as a valid heritage clause
|
||||
// element during recovery.
|
||||
return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
|
||||
}
|
||||
case ParsingContext.VariableDeclarations:
|
||||
return isIdentifierOrPattern();
|
||||
case ParsingContext.ArrayBindingElements:
|
||||
@@ -1641,21 +1661,44 @@ module ts {
|
||||
Debug.fail("Non-exhaustive case in 'isListElement'.");
|
||||
}
|
||||
|
||||
function isValidHeritageClauseObjectLiteral() {
|
||||
Debug.assert(token === SyntaxKind.OpenBraceToken);
|
||||
if (nextToken() === SyntaxKind.CloseBraceToken) {
|
||||
// if we see "extends {}" then only treat the {} as what we're extending (and not
|
||||
// the class body) if we have:
|
||||
//
|
||||
// extends {} {
|
||||
// extends {},
|
||||
// extends {} extends
|
||||
// extends {} implements
|
||||
|
||||
let next = nextToken();
|
||||
return next === SyntaxKind.CommaToken || next === SyntaxKind.OpenBraceToken || next === SyntaxKind.ExtendsKeyword || next === SyntaxKind.ImplementsKeyword;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifier() {
|
||||
nextToken();
|
||||
return isIdentifier();
|
||||
}
|
||||
|
||||
function isNotHeritageClauseTypeName(): boolean {
|
||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||
if (token === SyntaxKind.ImplementsKeyword ||
|
||||
token === SyntaxKind.ExtendsKeyword) {
|
||||
|
||||
return lookAhead(nextTokenIsIdentifier);
|
||||
return lookAhead(nextTokenIsStartOfExpression);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function nextTokenIsStartOfExpression() {
|
||||
nextToken();
|
||||
return isStartOfExpression();
|
||||
}
|
||||
|
||||
// True if positioned at a list terminator
|
||||
function isListTerminator(kind: ParsingContext): boolean {
|
||||
if (token === SyntaxKind.EndOfFileToken) {
|
||||
@@ -1676,7 +1719,7 @@ module ts {
|
||||
return token === SyntaxKind.CloseBraceToken;
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
|
||||
case ParsingContext.TypeReferences:
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.ExtendsKeyword || token === SyntaxKind.ImplementsKeyword;
|
||||
case ParsingContext.VariableDeclarations:
|
||||
return isVariableDeclaratorListTerminator();
|
||||
@@ -1793,7 +1836,7 @@ module ts {
|
||||
// some node, then we cannot get a node from the old source tree. This is because we
|
||||
// want to mark the next node we encounter as being unusable.
|
||||
//
|
||||
// Note: This may be too conservative. Perhaps we could reuse hte node and set the bit
|
||||
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
|
||||
// on it (or its leftmost child) as having the error. For now though, being conservative
|
||||
// is nice and likely won't ever affect perf.
|
||||
if (parseErrorBeforeNextFinishedNode) {
|
||||
@@ -1891,12 +1934,6 @@ module ts {
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// heritage clauses.
|
||||
|
||||
case ParsingContext.TypeReferences:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// type names in a heritage clause. There can be generic names in the type
|
||||
// name list. But because it is a type context, we never use speculative
|
||||
// parsing on the type argument list.
|
||||
|
||||
case ParsingContext.TypeParameters:
|
||||
// This would probably be safe to reuse. There is no speculative parsing with
|
||||
// type parameters. Note that that's because type *parameters* only occur in
|
||||
@@ -1923,6 +1960,12 @@ module ts {
|
||||
// cases. i.e. a property assignment may end with an expression, and thus might
|
||||
// have lookahead far beyond it's old node.
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
|
||||
// This is probably not safe to reuse. There can be speculative parsing with
|
||||
// type names in a heritage clause. There can be generic names in the type
|
||||
// name list, and there can be left hand side expressions (which can have type
|
||||
// arguments.)
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1957,6 +2000,7 @@ module ts {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2846,8 +2890,7 @@ module ts {
|
||||
}
|
||||
|
||||
// EXPRESSIONS
|
||||
|
||||
function isStartOfExpression(): boolean {
|
||||
function isStartOfLeftHandSideExpression(): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
@@ -2862,9 +2905,23 @@ module ts {
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.NewKeyword:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.SlashEqualsToken:
|
||||
case SyntaxKind.Identifier:
|
||||
return true;
|
||||
default:
|
||||
return isIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfExpression(): boolean {
|
||||
if (isStartOfLeftHandSideExpression()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case SyntaxKind.PlusToken:
|
||||
case SyntaxKind.MinusToken:
|
||||
case SyntaxKind.TildeToken:
|
||||
@@ -2875,7 +2932,6 @@ module ts {
|
||||
case SyntaxKind.PlusPlusToken:
|
||||
case SyntaxKind.MinusMinusToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.YieldKeyword:
|
||||
// Yield always starts an expression. Either it is an identifier (in which case
|
||||
// it is definitely an expression). Or it's a keyword (either because we're in
|
||||
@@ -2895,8 +2951,12 @@ module ts {
|
||||
}
|
||||
|
||||
function isStartOfExpressionStatement(): boolean {
|
||||
// As per the grammar, neither '{' nor 'function' can start an expression statement.
|
||||
return token !== SyntaxKind.OpenBraceToken && token !== SyntaxKind.FunctionKeyword && token !== SyntaxKind.AtToken && isStartOfExpression();
|
||||
// As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
|
||||
return token !== SyntaxKind.OpenBraceToken &&
|
||||
token !== SyntaxKind.FunctionKeyword &&
|
||||
token !== SyntaxKind.ClassKeyword &&
|
||||
token !== SyntaxKind.AtToken &&
|
||||
isStartOfExpression();
|
||||
}
|
||||
|
||||
function parseExpression(): Expression {
|
||||
@@ -3241,8 +3301,12 @@ module ts {
|
||||
return parseFunctionBlock(/*allowYield:*/ false, /* ignoreMissingOpenBrace */ false);
|
||||
}
|
||||
|
||||
if (isStartOfStatement(/*inErrorRecovery:*/ true) && !isStartOfExpressionStatement() && token !== SyntaxKind.FunctionKeyword) {
|
||||
// Check if we got a plain statement (i.e. no expression-statements, no functions expressions/declarations)
|
||||
if (isStartOfStatement(/*inErrorRecovery:*/ true) &&
|
||||
!isStartOfExpressionStatement() &&
|
||||
token !== SyntaxKind.FunctionKeyword &&
|
||||
token !== SyntaxKind.ClassKeyword) {
|
||||
|
||||
// Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
|
||||
//
|
||||
// Here we try to recover from a potential error situation in the case where the
|
||||
// user meant to supply a block. For example, if the user wrote:
|
||||
@@ -3667,7 +3731,6 @@ module ts {
|
||||
case SyntaxKind.CloseBracketToken: // foo<x>]
|
||||
case SyntaxKind.ColonToken: // foo<x>:
|
||||
case SyntaxKind.SemicolonToken: // foo<x>;
|
||||
case SyntaxKind.CommaToken: // foo<x>,
|
||||
case SyntaxKind.QuestionToken: // foo<x>?
|
||||
case SyntaxKind.EqualsEqualsToken: // foo<x> ==
|
||||
case SyntaxKind.EqualsEqualsEqualsToken: // foo<x> ===
|
||||
@@ -3685,6 +3748,12 @@ module ts {
|
||||
// treat it as such.
|
||||
return true;
|
||||
|
||||
case SyntaxKind.CommaToken: // foo<x>,
|
||||
case SyntaxKind.OpenBraceToken: // foo<x> {
|
||||
// We don't want to treat these as type arguments. Otherwise we'll parse this
|
||||
// as an invocation expression. Instead, we want to parse out the expression
|
||||
// in isolation from the type arguments.
|
||||
|
||||
default:
|
||||
// Anything else treat as an expression.
|
||||
return false;
|
||||
@@ -3709,6 +3778,8 @@ module ts {
|
||||
return parseArrayLiteralExpression();
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return parseObjectLiteralExpression();
|
||||
case SyntaxKind.ClassKeyword:
|
||||
return parseClassExpression();
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return parseFunctionExpression();
|
||||
case SyntaxKind.NewKeyword:
|
||||
@@ -4129,13 +4200,14 @@ module ts {
|
||||
}
|
||||
|
||||
function isStartOfStatement(inErrorRecovery: boolean): boolean {
|
||||
// Functions and variable statements are allowed as a statement. But as per the grammar,
|
||||
// they also allow modifiers. So we have to check for those statements that might be
|
||||
// following modifiers.This ensures that things work properly when incrementally parsing
|
||||
// as the parser will produce the same FunctionDeclaraiton or VariableStatement if it has
|
||||
// the same text regardless of whether it is inside a block or not.
|
||||
// Functions, variable statements and classes are allowed as a statement. But as per
|
||||
// the grammar, they also allow modifiers. So we have to check for those statements
|
||||
// that might be following modifiers.This ensures that things work properly when
|
||||
// incrementally parsing as the parser will produce the same FunctionDeclaraiton,
|
||||
// VariableStatement or ClassDeclaration, if it has the same text regardless of whether
|
||||
// it is inside a block or not.
|
||||
if (isModifier(token)) {
|
||||
let result = lookAhead(parseVariableStatementOrFunctionDeclarationWithDecoratorsOrModifiers);
|
||||
let result = lookAhead(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers);
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
@@ -4154,6 +4226,7 @@ module ts {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.IfKeyword:
|
||||
case SyntaxKind.DoKeyword:
|
||||
case SyntaxKind.WhileKeyword:
|
||||
@@ -4178,7 +4251,6 @@ module ts {
|
||||
let isConstEnum = lookAhead(nextTokenIsEnumKeyword);
|
||||
return !isConstEnum;
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
@@ -4222,6 +4294,8 @@ module ts {
|
||||
return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers:*/ undefined);
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return parseFunctionDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers:*/ undefined);
|
||||
case SyntaxKind.ClassKeyword:
|
||||
return parseClassDeclaration(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers:*/ undefined);
|
||||
case SyntaxKind.SemicolonToken:
|
||||
return parseEmptyStatement();
|
||||
case SyntaxKind.IfKeyword:
|
||||
@@ -4267,7 +4341,7 @@ module ts {
|
||||
// Even though variable statements and function declarations cannot have decorators,
|
||||
// we parse them here to provide better error recovery.
|
||||
if (isModifier(token) || token === SyntaxKind.AtToken) {
|
||||
let result = tryParse(parseVariableStatementOrFunctionDeclarationWithDecoratorsOrModifiers);
|
||||
let result = tryParse(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -4277,7 +4351,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseVariableStatementOrFunctionDeclarationWithDecoratorsOrModifiers(): FunctionDeclaration | VariableStatement {
|
||||
function parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers(): FunctionDeclaration | VariableStatement | ClassDeclaration {
|
||||
let start = scanner.getStartPos();
|
||||
let decorators = parseDecorators();
|
||||
let modifiers = parseModifiers();
|
||||
@@ -4297,8 +4371,12 @@ module ts {
|
||||
|
||||
case SyntaxKind.VarKeyword:
|
||||
return parseVariableStatement(start, decorators, modifiers);
|
||||
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return parseFunctionDeclaration(start, decorators, modifiers);
|
||||
|
||||
case SyntaxKind.ClassKeyword:
|
||||
return parseClassDeclaration(start, decorators, modifiers);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -4619,6 +4697,12 @@ module ts {
|
||||
}
|
||||
|
||||
function parseClassElement(): ClassElement {
|
||||
if (token === SyntaxKind.SemicolonToken) {
|
||||
let result = <SemicolonClassElement>createNode(SyntaxKind.SemicolonClassElement);
|
||||
nextToken();
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
let fullStart = getNodePos();
|
||||
let decorators = parseDecorators();
|
||||
let modifiers = parseModifiers();
|
||||
@@ -4657,18 +4741,28 @@ module ts {
|
||||
Debug.fail("Should not have attempted to parse class member declaration.");
|
||||
}
|
||||
|
||||
function parseClassExpression(): ClassExpression {
|
||||
return <ClassExpression>parseClassDeclarationOrExpression(
|
||||
/*fullStart:*/ scanner.getStartPos(),
|
||||
/*decorators:*/ undefined,
|
||||
/*modifiers:*/ undefined,
|
||||
SyntaxKind.ClassExpression);
|
||||
}
|
||||
|
||||
function parseClassDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ClassDeclaration {
|
||||
return <ClassDeclaration>parseClassDeclarationOrExpression(fullStart, decorators, modifiers, SyntaxKind.ClassDeclaration);
|
||||
}
|
||||
|
||||
function parseClassDeclarationOrExpression(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, kind: SyntaxKind): ClassLikeDeclaration {
|
||||
// In ES6 specification, All parts of a ClassDeclaration or a ClassExpression are strict mode code
|
||||
let savedStrictModeContext = inStrictModeContext();
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
setStrictModeContext(true);
|
||||
}
|
||||
setStrictModeContext(true);
|
||||
|
||||
var node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
|
||||
var node = <ClassLikeDeclaration>createNode(kind, fullStart);
|
||||
node.decorators = decorators;
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
|
||||
node.name = parseOptionalIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause:*/ true);
|
||||
|
||||
@@ -4714,13 +4808,23 @@ module ts {
|
||||
let node = <HeritageClause>createNode(SyntaxKind.HeritageClause);
|
||||
node.token = token;
|
||||
nextToken();
|
||||
node.types = parseDelimitedList(ParsingContext.TypeReferences, parseTypeReference);
|
||||
node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseHeritageClauseElement);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseHeritageClauseElement(): HeritageClauseElement {
|
||||
let node = <HeritageClauseElement>createNode(SyntaxKind.HeritageClauseElement);
|
||||
node.expression = parseLeftHandSideExpressionOrHigher();
|
||||
if (token === SyntaxKind.LessThanToken) {
|
||||
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function isHeritageClause(): boolean {
|
||||
return token === SyntaxKind.ExtendsKeyword || token === SyntaxKind.ImplementsKeyword;
|
||||
}
|
||||
@@ -5263,6 +5367,7 @@ module ts {
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
|
||||
+34
-7
@@ -8,7 +8,7 @@ module ts {
|
||||
/* @internal */ export let ioWriteTime = 0;
|
||||
|
||||
/** The version of the TypeScript compiler release */
|
||||
export let version = "1.5.0.0";
|
||||
export let version = "1.5.0";
|
||||
|
||||
export function findConfigFile(searchPath: string): string {
|
||||
var fileName = "tsconfig.json";
|
||||
@@ -454,6 +454,24 @@ module ts {
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
if (options.separateCompilation) {
|
||||
if (options.sourceMap) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation));
|
||||
}
|
||||
|
||||
if (options.declaration) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation));
|
||||
}
|
||||
|
||||
if (options.noEmitOnError) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation));
|
||||
}
|
||||
|
||||
if (options.out) {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation));
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
|
||||
// Error to specify --mapRoot or --sourceRoot without mapSourceFiles
|
||||
if (options.mapRoot) {
|
||||
@@ -468,12 +486,21 @@ module ts {
|
||||
let languageVersion = options.target || ScriptTarget.ES3;
|
||||
|
||||
let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
|
||||
if (firstExternalModuleSourceFile && !options.module) {
|
||||
if (options.separateCompilation) {
|
||||
if (!options.module && languageVersion < ScriptTarget.ES6) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
|
||||
diagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher));
|
||||
}
|
||||
|
||||
let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
|
||||
if (firstNonExternalModuleSourceFile) {
|
||||
let span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
|
||||
diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_non_external_modules_when_the_separateCompilation_flag_is_provided));
|
||||
}
|
||||
}
|
||||
else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
|
||||
diagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
|
||||
}
|
||||
|
||||
// Cannot specify module gen target when in es6 or above
|
||||
@@ -481,11 +508,11 @@ module ts {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher));
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourcRoot
|
||||
// there has to be common source directory if user specified --outdir || --sourceRoot
|
||||
// if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
|
||||
if (options.outDir || // there is --outDir specified
|
||||
options.sourceRoot || // there is --sourceRoot specified
|
||||
(options.mapRoot && // there is --mapRoot Specified and there would be multiple js files generated
|
||||
(options.mapRoot && // there is --mapRoot specified and there would be multiple js files generated
|
||||
(!options.out || firstExternalModuleSourceFile !== undefined))) {
|
||||
|
||||
let commonPathComponents: string[];
|
||||
|
||||
@@ -276,6 +276,7 @@ module ts {
|
||||
|
||||
// If a source file changes, mark it as unwatched and start the recompilation timer
|
||||
function sourceFileChanged(sourceFile: SourceFile) {
|
||||
sourceFile.fileWatcher.close();
|
||||
sourceFile.fileWatcher = undefined;
|
||||
startTimer();
|
||||
}
|
||||
|
||||
+30
-9
@@ -203,9 +203,12 @@ module ts {
|
||||
TemplateExpression,
|
||||
YieldExpression,
|
||||
SpreadElementExpression,
|
||||
ClassExpression,
|
||||
OmittedExpression,
|
||||
// Misc
|
||||
TemplateSpan,
|
||||
HeritageClauseElement,
|
||||
SemicolonClassElement,
|
||||
// Element
|
||||
Block,
|
||||
VariableStatement,
|
||||
@@ -536,6 +539,11 @@ module ts {
|
||||
body?: Block;
|
||||
}
|
||||
|
||||
// For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.
|
||||
export interface SemicolonClassElement extends ClassElement {
|
||||
_semicolonClassElementBrand: any;
|
||||
}
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind AccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
|
||||
@@ -728,6 +736,11 @@ module ts {
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
|
||||
export interface HeritageClauseElement extends Node {
|
||||
expression: LeftHandSideExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
}
|
||||
|
||||
export interface NewExpression extends CallExpression, PrimaryExpression { }
|
||||
|
||||
export interface TaggedTemplateExpression extends MemberExpression {
|
||||
@@ -849,13 +862,19 @@ module ts {
|
||||
_moduleElementBrand: any;
|
||||
}
|
||||
|
||||
export interface ClassDeclaration extends Declaration, ModuleElement {
|
||||
export interface ClassLikeDeclaration extends Declaration {
|
||||
name?: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
heritageClauses?: NodeArray<HeritageClause>;
|
||||
members: NodeArray<ClassElement>;
|
||||
}
|
||||
|
||||
export interface ClassDeclaration extends ClassLikeDeclaration, Statement {
|
||||
}
|
||||
|
||||
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
|
||||
}
|
||||
|
||||
export interface ClassElement extends Declaration {
|
||||
_classElementBrand: any;
|
||||
}
|
||||
@@ -869,7 +888,7 @@ module ts {
|
||||
|
||||
export interface HeritageClause extends Node {
|
||||
token: SyntaxKind;
|
||||
types?: NodeArray<TypeReferenceNode>;
|
||||
types?: NodeArray<HeritageClauseElement>;
|
||||
}
|
||||
|
||||
export interface TypeAliasDeclaration extends Declaration, ModuleElement {
|
||||
@@ -914,7 +933,7 @@ module ts {
|
||||
// import "mod" => importClause = undefined, moduleSpecifier = "mod"
|
||||
// In rest of the cases, module specifier is string literal corresponding to module
|
||||
// ImportClause information is shown at its declaration below.
|
||||
export interface ImportDeclaration extends Statement, ModuleElement {
|
||||
export interface ImportDeclaration extends ModuleElement {
|
||||
importClause?: ImportClause;
|
||||
moduleSpecifier: Expression;
|
||||
}
|
||||
@@ -1127,7 +1146,7 @@ module ts {
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
|
||||
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
getExportsOfExternalModule(node: ImportDeclaration): Symbol[];
|
||||
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
@@ -1231,11 +1250,14 @@ module ts {
|
||||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult;
|
||||
isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult;
|
||||
isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult;
|
||||
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
|
||||
resolvesToSomeValue(location: Node, name: string): boolean;
|
||||
getBlockScopedVariableId(node: Identifier): number;
|
||||
serializeTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[];
|
||||
serializeParameterTypesOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): (string | string[])[];
|
||||
serializeReturnTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[];
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -1361,6 +1383,7 @@ module ts {
|
||||
EnumValuesComputed = 0x00000080,
|
||||
BlockScopedBindingInLoop = 0x00000100,
|
||||
EmitDecorate = 0x00000200, // Emit __decorate
|
||||
EmitParam = 0x00000400, // Emit __param helper for decorators
|
||||
}
|
||||
|
||||
export interface NodeLinks {
|
||||
@@ -1560,7 +1583,6 @@ module ts {
|
||||
export interface CompilerOptions {
|
||||
allowNonTsExtensions?: boolean;
|
||||
charset?: string;
|
||||
codepage?: number;
|
||||
declaration?: boolean;
|
||||
diagnostics?: boolean;
|
||||
emitBOM?: boolean;
|
||||
@@ -1574,7 +1596,6 @@ module ts {
|
||||
noErrorTruncation?: boolean;
|
||||
noImplicitAny?: boolean;
|
||||
noLib?: boolean;
|
||||
noLibCheck?: boolean;
|
||||
noResolve?: boolean;
|
||||
out?: string;
|
||||
outDir?: string;
|
||||
@@ -1587,9 +1608,9 @@ module ts {
|
||||
target?: ScriptTarget;
|
||||
version?: boolean;
|
||||
watch?: boolean;
|
||||
separateCompilation?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
/* @internal */ preserveNewLines?: boolean;
|
||||
/* @internal */ cacheDownlevelForOfLength?: boolean;
|
||||
[option: string]: string | number | boolean;
|
||||
}
|
||||
|
||||
|
||||
+84
-10
@@ -145,7 +145,7 @@ module ts {
|
||||
|
||||
return node.pos === node.end && node.kind !== SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
|
||||
export function nodeIsPresent(node: Node) {
|
||||
return !nodeIsMissing(node);
|
||||
}
|
||||
@@ -274,11 +274,19 @@ module ts {
|
||||
export function getErrorSpanForNode(sourceFile: SourceFile, node: Node): TextSpan {
|
||||
let errorNode = node;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
let pos = skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
|
||||
if (pos === sourceFile.text.length) {
|
||||
// file is empty - return span for the beginning of the file
|
||||
return createTextSpan(0, 0);
|
||||
}
|
||||
return getSpanOfTokenAtPosition(sourceFile, pos);
|
||||
// This list is a work in progress. Add missing node kinds to improve their error
|
||||
// spans.
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
@@ -288,7 +296,7 @@ module ts {
|
||||
errorNode = (<Declaration>node).name;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (errorNode === undefined) {
|
||||
// If we don't have a better node, then just set the error on the first token of
|
||||
// construct.
|
||||
@@ -441,6 +449,18 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isAccessor(node: Node): boolean {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isFunctionLike(node: Node): boolean {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
@@ -506,6 +526,19 @@ module ts {
|
||||
// the *body* of the container.
|
||||
node = node.parent;
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
// Decorators are always applied outside of the body of a class or method.
|
||||
if (node.parent.kind === SyntaxKind.Parameter && isClassElement(node.parent.parent)) {
|
||||
// If the decorator's parent is a Parameter, we resolve the this container from
|
||||
// the grandparent class declaration.
|
||||
node = node.parent.parent;
|
||||
}
|
||||
else if (isClassElement(node.parent)) {
|
||||
// If the decorator's parent is a class element, we resolve the 'this' container
|
||||
// from the parent class declaration.
|
||||
node = node.parent;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
if (!includeArrowFunctions) {
|
||||
continue;
|
||||
@@ -548,6 +581,19 @@ module ts {
|
||||
// the *body* of the container.
|
||||
node = node.parent;
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
// Decorators are always applied outside of the body of a class or method.
|
||||
if (node.parent.kind === SyntaxKind.Parameter && isClassElement(node.parent.parent)) {
|
||||
// If the decorator's parent is a Parameter, we resolve the this container from
|
||||
// the grandparent class declaration.
|
||||
node = node.parent.parent;
|
||||
}
|
||||
else if (isClassElement(node.parent)) {
|
||||
// If the decorator's parent is a class element, we resolve the 'this' container
|
||||
// from the parent class declaration.
|
||||
node = node.parent;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
@@ -634,7 +680,7 @@ module ts {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
export function childIsDecorated(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
@@ -670,6 +716,7 @@ module ts {
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
@@ -745,7 +792,7 @@ module ts {
|
||||
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
|
||||
let moduleState = getModuleInstanceState(node)
|
||||
return moduleState === ModuleInstanceState.Instantiated ||
|
||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||
(preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly);
|
||||
}
|
||||
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node) {
|
||||
@@ -898,6 +945,7 @@ module ts {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
return true;
|
||||
default:
|
||||
@@ -942,12 +990,12 @@ module ts {
|
||||
node.kind === SyntaxKind.ExportAssignment && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
export function getClassBaseTypeNode(node: ClassDeclaration) {
|
||||
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration) {
|
||||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword);
|
||||
return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
|
||||
}
|
||||
|
||||
export function getClassImplementedTypeNodes(node: ClassDeclaration) {
|
||||
export function getClassImplementsHeritageClauseElements(node: ClassDeclaration) {
|
||||
let heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ImplementsKeyword);
|
||||
return heritageClause ? heritageClause.types : undefined;
|
||||
}
|
||||
@@ -1161,7 +1209,7 @@ module ts {
|
||||
export function createTextSpanFromBounds(start: number, end: number) {
|
||||
return createTextSpan(start, end - start);
|
||||
}
|
||||
|
||||
|
||||
export function textChangeRangeNewSpan(range: TextChangeRange) {
|
||||
return createTextSpan(range.span.start, range.newLength);
|
||||
}
|
||||
@@ -1435,13 +1483,13 @@ module ts {
|
||||
return escapedCharsMap[c] || get16BitUnicodeEscapeSequence(c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get16BitUnicodeEscapeSequence(charCode: number): string {
|
||||
let hexCharCode = charCode.toString(16).toUpperCase();
|
||||
let paddedHexCode = ("0000" + hexCharCode).slice(-4);
|
||||
return "\\u" + paddedHexCode;
|
||||
}
|
||||
|
||||
|
||||
let nonAsciiCharacters = /[^\u0000-\u007F]/g;
|
||||
export function escapeNonAsciiCharacters(s: string): string {
|
||||
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
|
||||
@@ -1573,7 +1621,7 @@ module ts {
|
||||
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
||||
}
|
||||
|
||||
export function getFirstConstructorWithBody(node: ClassDeclaration): ConstructorDeclaration {
|
||||
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
|
||||
return forEach(node.members, member => {
|
||||
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
|
||||
return <ConstructorDeclaration>member;
|
||||
@@ -1768,4 +1816,30 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns false if this heritage clause element's expression contains something unsupported
|
||||
// (i.e. not a name or dotted name).
|
||||
export function isSupportedHeritageClauseElement(node: HeritageClauseElement): boolean {
|
||||
return isSupportedHeritageClauseElementExpression(node.expression);
|
||||
}
|
||||
|
||||
function isSupportedHeritageClauseElementExpression(node: Expression): boolean {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
return true;
|
||||
}
|
||||
else if (node.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
return isSupportedHeritageClauseElementExpression((<PropertyAccessExpression>node).expression);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {
|
||||
return (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node) ||
|
||||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);
|
||||
}
|
||||
|
||||
export function getLocalSymbolForExportDefault(symbol: Symbol) {
|
||||
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-18
@@ -14,6 +14,7 @@
|
||||
//
|
||||
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='harnessLanguageService.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='fourslashRunner.ts' />
|
||||
@@ -115,7 +116,7 @@ module FourSlash {
|
||||
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
|
||||
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
|
||||
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
|
||||
var testOptMetadataNames = {
|
||||
var metadataOptionNames = {
|
||||
baselineFile: 'BaselineFile',
|
||||
declaration: 'declaration',
|
||||
emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
|
||||
@@ -126,14 +127,15 @@ module FourSlash {
|
||||
outDir: 'outDir',
|
||||
sourceMap: 'sourceMap',
|
||||
sourceRoot: 'sourceRoot',
|
||||
allowNonTsExtensions: 'allowNonTsExtensions',
|
||||
resolveReference: 'ResolveReference', // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
|
||||
};
|
||||
|
||||
// List of allowed metadata names
|
||||
var fileMetadataNames = [testOptMetadataNames.fileName, testOptMetadataNames.emitThisFile, testOptMetadataNames.resolveReference];
|
||||
var globalMetadataNames = [testOptMetadataNames.baselineFile, testOptMetadataNames.declaration,
|
||||
testOptMetadataNames.mapRoot, testOptMetadataNames.module, testOptMetadataNames.out,
|
||||
testOptMetadataNames.outDir, testOptMetadataNames.sourceMap, testOptMetadataNames.sourceRoot]
|
||||
var fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference];
|
||||
var globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration,
|
||||
metadataOptionNames.mapRoot, metadataOptionNames.module, metadataOptionNames.out,
|
||||
metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot]
|
||||
|
||||
function convertGlobalOptionsToCompilerOptions(globalOptions: { [idx: string]: string }): ts.CompilerOptions {
|
||||
var settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 };
|
||||
@@ -141,13 +143,16 @@ module FourSlash {
|
||||
for (var prop in globalOptions) {
|
||||
if (globalOptions.hasOwnProperty(prop)) {
|
||||
switch (prop) {
|
||||
case testOptMetadataNames.declaration:
|
||||
case metadataOptionNames.allowNonTsExtensions:
|
||||
settings.allowNonTsExtensions = true;
|
||||
break;
|
||||
case metadataOptionNames.declaration:
|
||||
settings.declaration = true;
|
||||
break;
|
||||
case testOptMetadataNames.mapRoot:
|
||||
case metadataOptionNames.mapRoot:
|
||||
settings.mapRoot = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.module:
|
||||
case metadataOptionNames.module:
|
||||
// create appropriate external module target for CompilationSettings
|
||||
switch (globalOptions[prop]) {
|
||||
case "AMD":
|
||||
@@ -162,16 +167,16 @@ module FourSlash {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case testOptMetadataNames.out:
|
||||
case metadataOptionNames.out:
|
||||
settings.out = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.outDir:
|
||||
case metadataOptionNames.outDir:
|
||||
settings.outDir = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.sourceMap:
|
||||
case metadataOptionNames.sourceMap:
|
||||
settings.sourceMap = true;
|
||||
break;
|
||||
case testOptMetadataNames.sourceRoot:
|
||||
case metadataOptionNames.sourceRoot:
|
||||
settings.sourceRoot = globalOptions[prop];
|
||||
break;
|
||||
}
|
||||
@@ -303,7 +308,7 @@ module FourSlash {
|
||||
ts.forEach(testData.files, file => {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles[file.fileName] = file.content;
|
||||
if (!startResolveFileRef && file.fileOptions[testOptMetadataNames.resolveReference]) {
|
||||
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference]) {
|
||||
startResolveFileRef = file;
|
||||
} else if (startResolveFileRef) {
|
||||
// If entry point for resolving file references is already specified, report duplication error
|
||||
@@ -793,6 +798,13 @@ module FourSlash {
|
||||
return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue;
|
||||
}
|
||||
|
||||
public getSemanticDiagnostics(expected: string) {
|
||||
var diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName);
|
||||
var realized = ts.realizeDiagnostics(diagnostics, "\r\n");
|
||||
var actual = JSON.stringify(realized, null, " ");
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
public verifyQuickInfoString(negative: boolean, expectedText?: string, expectedDocumentation?: string) {
|
||||
[expectedText, expectedDocumentation].forEach(str => {
|
||||
if (str) {
|
||||
@@ -1131,7 +1143,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Breakpoint Locations for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
|
||||
},
|
||||
@@ -1146,7 +1158,7 @@ module FourSlash {
|
||||
var allFourSlashFiles = this.testData.files;
|
||||
for (var idx = 0; idx < allFourSlashFiles.length; ++idx) {
|
||||
var file = allFourSlashFiles[idx];
|
||||
if (file.fileOptions[testOptMetadataNames.emitThisFile]) {
|
||||
if (file.fileOptions[metadataOptionNames.emitThisFile]) {
|
||||
// Find a file with the flag emitThisFile turned on
|
||||
emitFiles.push(file);
|
||||
}
|
||||
@@ -1159,7 +1171,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Generate getEmitOutput baseline : " + emitFiles.join(" "),
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
var resultString = "";
|
||||
// Loop through all the emittedFiles and emit them one by one
|
||||
@@ -1704,7 +1716,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Name OrDottedNameSpans for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos));
|
||||
@@ -2280,7 +2292,7 @@ module FourSlash {
|
||||
if (globalMetadataNamesIndex === -1) {
|
||||
if (fileMetadataNamesIndex === -1) {
|
||||
throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', '));
|
||||
} else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(testOptMetadataNames.fileName)) {
|
||||
} else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) {
|
||||
// Found an @FileName directive, if this is not the first then create a new subfile
|
||||
if (currentFileContent) {
|
||||
var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
|
||||
|
||||
+33
-21
@@ -781,7 +781,7 @@ module Harness {
|
||||
|
||||
public reset() { this.fileCollection = {}; }
|
||||
|
||||
public toArray(): { fileName: string; file: WriterAggregator; }[] {
|
||||
public toArray(): { fileName: string; file: WriterAggregator; }[]{
|
||||
var result: { fileName: string; file: WriterAggregator; }[] = [];
|
||||
for (var p in this.fileCollection) {
|
||||
if (this.fileCollection.hasOwnProperty(p)) {
|
||||
@@ -944,6 +944,10 @@ module Harness {
|
||||
|
||||
var newLine = '\r\n';
|
||||
|
||||
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
|
||||
// Treat them as library files, so include them in build, but not in baselines.
|
||||
var includeBuiltFiles: { unitName: string; content: string }[] = [];
|
||||
|
||||
var useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
|
||||
this.settings.forEach(setting => {
|
||||
switch (setting.flag.toLowerCase()) {
|
||||
@@ -1008,10 +1012,6 @@ module Harness {
|
||||
options.outDir = setting.value;
|
||||
break;
|
||||
|
||||
case 'preservenewlines':
|
||||
options.preserveNewLines = !!setting.value;
|
||||
break;
|
||||
|
||||
case 'sourceroot':
|
||||
options.sourceRoot = setting.value;
|
||||
break;
|
||||
@@ -1040,17 +1040,7 @@ module Harness {
|
||||
useCaseSensitiveFileNames = setting.value === 'true';
|
||||
break;
|
||||
|
||||
case 'mapsourcefiles':
|
||||
case 'maproot':
|
||||
case 'generatedeclarationfiles':
|
||||
case 'gatherDiagnostics':
|
||||
case 'codepage':
|
||||
case 'createFileLog':
|
||||
case 'filename':
|
||||
case 'removecomments':
|
||||
case 'watch':
|
||||
case 'allowautomaticsemicoloninsertion':
|
||||
case 'locale':
|
||||
// Not supported yet
|
||||
break;
|
||||
|
||||
@@ -1066,23 +1056,28 @@ module Harness {
|
||||
options.preserveConstEnums = setting.value === 'true';
|
||||
break;
|
||||
|
||||
case 'separatecompilation':
|
||||
options.separateCompilation = setting.value === 'true';
|
||||
break;
|
||||
|
||||
case 'suppressimplicitanyindexerrors':
|
||||
options.suppressImplicitAnyIndexErrors = setting.value === 'true';
|
||||
break;
|
||||
|
||||
case 'includebuiltfile':
|
||||
inputFiles.push({ unitName: setting.value, content: normalizeLineEndings(IO.readFile(libFolder + setting.value), newLine) });
|
||||
let builtFileName = libFolder + setting.value;
|
||||
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unsupported compiler setting ' + setting.flag);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
var programFiles = inputFiles.map(file => file.unitName);
|
||||
var program = ts.createProgram(programFiles, options, createCompilerHost(inputFiles.concat(otherFiles),
|
||||
var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||
var program = ts.createProgram(programFiles, options, createCompilerHost(inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||
options.target, useCaseSensitiveFileNames, currentDirectory));
|
||||
|
||||
@@ -1305,7 +1300,7 @@ module Harness {
|
||||
});
|
||||
|
||||
var numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
return diagnostic.fileName && isLibraryFile(diagnostic.fileName);
|
||||
return diagnostic.fileName && (isLibraryFile(diagnostic.fileName) || isBuiltFile(diagnostic.fileName));
|
||||
});
|
||||
|
||||
var numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
@@ -1465,7 +1460,12 @@ module Harness {
|
||||
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
||||
|
||||
// List of allowed metadata names
|
||||
var fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noemitonerror", "noimplicitany", "noresolve", "newline", "newlines", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums", "preservenewlines", "includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal"];
|
||||
var fileMetadataNames = ["filename", "comments", "declaration", "module",
|
||||
"nolib", "sourcemap", "target", "out", "outdir", "noemitonerror",
|
||||
"noimplicitany", "noresolve", "newline", "newlines", "emitbom",
|
||||
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
|
||||
"includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal",
|
||||
"separatecompilation"];
|
||||
|
||||
function extractCompilerSettings(content: string): CompilerSetting[] {
|
||||
|
||||
@@ -1703,6 +1703,18 @@ module Harness {
|
||||
return (Path.getFileName(filePath) === 'lib.d.ts') || (Path.getFileName(filePath) === 'lib.core.d.ts');
|
||||
}
|
||||
|
||||
export function isBuiltFile(filePath: string): boolean {
|
||||
return filePath.indexOf(Harness.libFolder) === 0;
|
||||
}
|
||||
|
||||
export function getDefaultLibraryFile(): { unitName: string, content: string } {
|
||||
var libFile = Harness.userSpecifiedroot + Harness.libFolder + "/" + "lib.d.ts";
|
||||
return {
|
||||
unitName: libFile,
|
||||
content: IO.readFile(libFile)
|
||||
}
|
||||
}
|
||||
|
||||
if (Error) (<any>Error).stackTraceLimit = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ interface IOLog {
|
||||
arguments: string[];
|
||||
executingPath: string;
|
||||
currentDirectory: string;
|
||||
useCustomLibraryFile?: boolean;
|
||||
filesRead: {
|
||||
path: string;
|
||||
codepage: number;
|
||||
|
||||
+38
-14
@@ -32,6 +32,7 @@ module RWC {
|
||||
};
|
||||
var baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
var currentDirectory: string;
|
||||
var useCustomLibraryFile: boolean;
|
||||
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
@@ -43,6 +44,10 @@ module RWC {
|
||||
baselineOpts = undefined;
|
||||
baseName = undefined;
|
||||
currentDirectory = undefined;
|
||||
// useCustomLibraryFile is a flag specified in the json object to indicate whether to use built/local/lib.d.ts
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
useCustomLibraryFile = undefined;
|
||||
});
|
||||
|
||||
it('can compile', () => {
|
||||
@@ -51,34 +56,52 @@ module RWC {
|
||||
|
||||
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments);
|
||||
assert.equal(opts.errors.length, 0);
|
||||
|
||||
// To provide test coverage of output javascript file,
|
||||
// we will set noEmitOnError flag to be false.
|
||||
opts.options.noEmitOnError = false;
|
||||
});
|
||||
|
||||
runWithIOLog(ioLog, () => {
|
||||
harnessCompiler.reset();
|
||||
|
||||
// Load the files
|
||||
ts.forEach(opts.fileNames, fileName => {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
});
|
||||
|
||||
if (!opts.options.noLib) {
|
||||
// Find the lib.d.ts file in the input file and add it to the input files list
|
||||
var libFile = ts.forEach(ioLog.filesRead, fileRead=> Harness.isLibraryFile(fileRead.path) ? fileRead.path : undefined);
|
||||
if (libFile) {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(libFile));
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEach(ioLog.filesRead, fileRead => {
|
||||
// Add files to compilation
|
||||
for(let fileRead of ioLog.filesRead) {
|
||||
// Check if the file is already added into the set of input files.
|
||||
var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
|
||||
var inInputList = ts.forEach(inputFiles, inputFile=> inputFile.unitName === resolvedPath);
|
||||
if (!inInputList) {
|
||||
// Add the file to other files
|
||||
var inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath);
|
||||
|
||||
if (!Harness.isLibraryFile(fileRead.path)) {
|
||||
if (inInputList) {
|
||||
continue;
|
||||
}
|
||||
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
});
|
||||
else if (!opts.options.noLib && Harness.isLibraryFile(fileRead.path)){
|
||||
if (!inInputList) {
|
||||
// If useCustomLibraryFile is true, we will use lib.d.ts from json object
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
// Majority of RWC code will be using built/local/lib.d.ts instead of
|
||||
// lib.d.ts inside json file. However, some RWC cases will still use
|
||||
// their own version of lib.d.ts because they have customized lib.d.ts
|
||||
if (useCustomLibraryFile) {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileRead.path));
|
||||
}
|
||||
else {
|
||||
inputFiles.push(Harness.getDefaultLibraryFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do not use lib since we already read it in above
|
||||
opts.options.noLib = true;
|
||||
@@ -115,9 +138,10 @@ module RWC {
|
||||
|
||||
it('has the expected declaration file content', () => {
|
||||
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
|
||||
if (compilerResult.errors.length || !compilerResult.declFilesCode.length) {
|
||||
if (!compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.collateOutputs(compilerResult.declFilesCode);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
@@ -38,7 +38,6 @@ class TypeWriterWalker {
|
||||
case ts.SyntaxKind.SuperKeyword:
|
||||
case ts.SyntaxKind.ArrayLiteralExpression:
|
||||
case ts.SyntaxKind.ObjectLiteralExpression:
|
||||
case ts.SyntaxKind.PropertyAccessExpression:
|
||||
case ts.SyntaxKind.ElementAccessExpression:
|
||||
case ts.SyntaxKind.CallExpression:
|
||||
case ts.SyntaxKind.NewExpression:
|
||||
@@ -57,6 +56,14 @@ class TypeWriterWalker {
|
||||
this.log(node, this.getTypeOfNode(node));
|
||||
break;
|
||||
|
||||
case ts.SyntaxKind.PropertyAccessExpression:
|
||||
for (var current = node; current.kind === ts.SyntaxKind.PropertyAccessExpression; current = current.parent) {
|
||||
}
|
||||
if (current.kind !== ts.SyntaxKind.HeritageClauseElement) {
|
||||
this.log(node, this.getTypeOfNode(node));
|
||||
}
|
||||
break;
|
||||
|
||||
// Should not change expression status (maybe expressions)
|
||||
// TODO: Again, ideally should log number and string literals too,
|
||||
// but to be consistent with the old typeWriter, just log identifiers
|
||||
|
||||
Vendored
+1
-1
@@ -1168,4 +1168,4 @@ interface TypedPropertyDescriptor<T> {
|
||||
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
|
||||
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
|
||||
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
|
||||
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;
|
||||
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
|
||||
|
||||
Vendored
+18
-18
@@ -3513,27 +3513,27 @@ interface ProxyHandler<T> {
|
||||
|
||||
interface ProxyConstructor {
|
||||
revocable<T>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };
|
||||
new <T>(target: T, handeler: ProxyHandler<T>): T
|
||||
new <T>(target: T, handler: ProxyHandler<T>): T
|
||||
}
|
||||
declare var Proxy: ProxyConstructor;
|
||||
|
||||
declare var Reflect: {
|
||||
apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
||||
construct(target: Function, argumentsList: ArrayLike<any>): any;
|
||||
defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
||||
deleteProperty(target: any, propertyKey: PropertyKey): boolean;
|
||||
enumerate(target: any): IterableIterator<any>;
|
||||
get(target: any, propertyKey: PropertyKey, receiver?: any): any;
|
||||
getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
getPrototypeOf(target: any): any;
|
||||
has(target: any, propertyKey: string): boolean;
|
||||
has(target: any, propertyKey: symbol): boolean;
|
||||
isExtensible(target: any): boolean;
|
||||
ownKeys(target: any): Array<PropertyKey>;
|
||||
preventExtensions(target: any): boolean;
|
||||
set(target: any, propertyKey: PropertyKey, value: any, receiver? :any): boolean;
|
||||
setPrototypeOf(target: any, proto: any): boolean;
|
||||
};
|
||||
declare module Reflect {
|
||||
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
||||
function construct(target: Function, argumentsList: ArrayLike<any>): any;
|
||||
function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
||||
function deleteProperty(target: any, propertyKey: PropertyKey): boolean;
|
||||
function enumerate(target: any): IterableIterator<any>;
|
||||
function get(target: any, propertyKey: PropertyKey, receiver?: any): any;
|
||||
function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
function getPrototypeOf(target: any): any;
|
||||
function has(target: any, propertyKey: string): boolean;
|
||||
function has(target: any, propertyKey: symbol): boolean;
|
||||
function isExtensible(target: any): boolean;
|
||||
function ownKeys(target: any): Array<PropertyKey>;
|
||||
function preventExtensions(target: any): boolean;
|
||||
function set(target: any, propertyKey: PropertyKey, value: any, receiver? :any): boolean;
|
||||
function setPrototypeOf(target: any, proto: any): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
|
||||
Vendored
+158
-8
@@ -4,7 +4,11 @@
|
||||
/// Windows Script Host APIS
|
||||
/////////////////////////////
|
||||
|
||||
declare var ActiveXObject: { new (s: string): any; };
|
||||
|
||||
interface ActiveXObject {
|
||||
new (s: string): any;
|
||||
}
|
||||
declare var ActiveXObject: ActiveXObject;
|
||||
|
||||
interface ITextWriter {
|
||||
Write(s: string): void;
|
||||
@@ -12,11 +16,157 @@ interface ITextWriter {
|
||||
Close(): void;
|
||||
}
|
||||
|
||||
declare var WScript: {
|
||||
Echo(s: any): void;
|
||||
StdErr: ITextWriter;
|
||||
StdOut: ITextWriter;
|
||||
Arguments: { length: number; Item(n: number): string; };
|
||||
ScriptFullName: string;
|
||||
Quit(exitCode?: number): number;
|
||||
interface TextStreamBase {
|
||||
/**
|
||||
* The column number of the current character position in an input stream.
|
||||
*/
|
||||
Column: number;
|
||||
/**
|
||||
* The current line number in an input stream.
|
||||
*/
|
||||
Line: number;
|
||||
/**
|
||||
* Closes a text stream.
|
||||
* It is not necessary to close standard streams; they close automatically when the process ends. If you close a standard stream, be aware that any other pointers to that standard stream become invalid.
|
||||
*/
|
||||
Close(): void;
|
||||
}
|
||||
|
||||
interface TextStreamWriter extends TextStreamBase {
|
||||
/**
|
||||
* Sends a string to an output stream.
|
||||
*/
|
||||
Write(s: string): void;
|
||||
/**
|
||||
* Sends a specified number of blank lines (newline characters) to an output stream.
|
||||
*/
|
||||
WriteBlankLines(intLines: number): void;
|
||||
/**
|
||||
* Sends a string followed by a newline character to an output stream.
|
||||
*/
|
||||
WriteLine(s: string): void;
|
||||
}
|
||||
|
||||
interface TextStreamReader extends TextStreamBase {
|
||||
/**
|
||||
* Returns a specified number of characters from an input stream, beginning at the current pointer position.
|
||||
* Does not return until the ENTER key is pressed.
|
||||
* Can only be used on a stream in reading mode; causes an error in writing or appending mode.
|
||||
*/
|
||||
Read(characters: number): string;
|
||||
/**
|
||||
* Returns all characters from an input stream.
|
||||
* Can only be used on a stream in reading mode; causes an error in writing or appending mode.
|
||||
*/
|
||||
ReadAll(): string;
|
||||
/**
|
||||
* Returns an entire line from an input stream.
|
||||
* Although this method extracts the newline character, it does not add it to the returned string.
|
||||
* Can only be used on a stream in reading mode; causes an error in writing or appending mode.
|
||||
*/
|
||||
ReadLine(): string;
|
||||
/**
|
||||
* Skips a specified number of characters when reading from an input text stream.
|
||||
* Can only be used on a stream in reading mode; causes an error in writing or appending mode.
|
||||
* @param characters Positive number of characters to skip forward. (Backward skipping is not supported.)
|
||||
*/
|
||||
Skip(characters: number): void;
|
||||
/**
|
||||
* Skips the next line when reading from an input text stream.
|
||||
* Can only be used on a stream in reading mode, not writing or appending mode.
|
||||
*/
|
||||
SkipLine(): void;
|
||||
/**
|
||||
* Indicates whether the stream pointer position is at the end of a line.
|
||||
*/
|
||||
AtEndOfLine: boolean;
|
||||
/**
|
||||
* Indicates whether the stream pointer position is at the end of a stream.
|
||||
*/
|
||||
AtEndOfStream: boolean;
|
||||
}
|
||||
|
||||
declare var WScript: {
|
||||
/**
|
||||
* Outputs text to either a message box (under WScript.exe) or the command console window followed by a newline (under CScript.ext).
|
||||
*/
|
||||
Echo(s: any): void;
|
||||
/**
|
||||
* Exposes the write-only error output stream for the current script.
|
||||
* Can be accessed only while using CScript.exe.
|
||||
*/
|
||||
StdErr: TextStreamWriter;
|
||||
/**
|
||||
* Exposes the write-only output stream for the current script.
|
||||
* Can be accessed only while using CScript.exe.
|
||||
*/
|
||||
StdOut: TextStreamWriter;
|
||||
Arguments: { length: number; Item(n: number): string; };
|
||||
/**
|
||||
* The full path of the currently running script.
|
||||
*/
|
||||
ScriptFullName: string;
|
||||
/**
|
||||
* Forces the script to stop immediately, with an optional exit code.
|
||||
*/
|
||||
Quit(exitCode?: number): number;
|
||||
/**
|
||||
* The Windows Script Host build version number.
|
||||
*/
|
||||
BuildVersion: number;
|
||||
/**
|
||||
* Fully qualified path of the host executable.
|
||||
*/
|
||||
FullName: string;
|
||||
/**
|
||||
* Gets/sets the script mode - interactive(true) or batch(false).
|
||||
*/
|
||||
Interactive: boolean;
|
||||
/**
|
||||
* The name of the host executable (WScript.exe or CScript.exe).
|
||||
*/
|
||||
Name: string;
|
||||
/**
|
||||
* Path of the directory containing the host executable.
|
||||
*/
|
||||
Path: string;
|
||||
/**
|
||||
* The filename of the currently running script.
|
||||
*/
|
||||
ScriptName: string;
|
||||
/**
|
||||
* Exposes the read-only input stream for the current script.
|
||||
* Can be accessed only while using CScript.exe.
|
||||
*/
|
||||
StdIn: TextStreamReader;
|
||||
/**
|
||||
* Windows Script Host version
|
||||
*/
|
||||
Version: string;
|
||||
/**
|
||||
* Connects a COM object's event sources to functions named with a given prefix, in the form prefix_event.
|
||||
*/
|
||||
ConnectObject(objEventSource: any, strPrefix: string): void;
|
||||
/**
|
||||
* Creates a COM object.
|
||||
* @param strProgiID
|
||||
* @param strPrefix Function names in the form prefix_event will be bound to this object's COM events.
|
||||
*/
|
||||
CreateObject(strProgID: string, strPrefix?: string): any;
|
||||
/**
|
||||
* Disconnects a COM object from its event sources.
|
||||
*/
|
||||
DisconnectObject(obj: any): void;
|
||||
/**
|
||||
* Retrieves an existing object with the specified ProgID from memory, or creates a new one from a file.
|
||||
* @param strPathname Fully qualified path to the file containing the object persisted to disk. For objects in memory, pass a zero-length string.
|
||||
* @param strProgID
|
||||
* @param strPrefix Function names in the form prefix_event will be bound to this object's COM events.
|
||||
*/
|
||||
GetObject(strPathname: string, strProgID?: string, strPrefix?: string): any;
|
||||
/**
|
||||
* Suspends script execution for a specified length of time, then continues execution.
|
||||
* @param intTime Interval (in milliseconds) to suspend script execution.
|
||||
*/
|
||||
Sleep(intTime: number): void;
|
||||
};
|
||||
|
||||
@@ -68,12 +68,12 @@ module ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private processRequest<T extends protocol.Request>(command: string, arguments?: any): T {
|
||||
private processRequest<T extends protocol.Request>(command: string, args?: any): T {
|
||||
var request: protocol.Request = {
|
||||
seq: this.sequence++,
|
||||
type: "request",
|
||||
command: command,
|
||||
arguments: arguments
|
||||
arguments: args,
|
||||
command
|
||||
};
|
||||
|
||||
this.writeMessage(JSON.stringify(request));
|
||||
|
||||
@@ -458,7 +458,7 @@ module ts.server {
|
||||
var info = this.filenameToScriptInfo[args.file];
|
||||
if (info) {
|
||||
info.setFormatOptions(args.formatOptions);
|
||||
this.log("Host configuration update for file " + args.file);
|
||||
this.log("Host configuration update for file " + args.file, "Info");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -764,6 +764,26 @@ module ts.server {
|
||||
return info;
|
||||
}
|
||||
|
||||
// This is different from the method the compiler uses because
|
||||
// the compiler can assume it will always start searching in the
|
||||
// current directory (the directory in which tsc was invoked).
|
||||
// The server must start searching from the directory containing
|
||||
// the newly opened file.
|
||||
findConfigFile(searchPath: string): string {
|
||||
while (true) {
|
||||
var fileName = ts.combinePaths(searchPath, "tsconfig.json");
|
||||
if (sys.fileExists(fileName)) {
|
||||
return fileName;
|
||||
}
|
||||
var parentPath = ts.getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open file whose contents is managed by the client
|
||||
* @param filename is absolute pathname
|
||||
@@ -771,7 +791,13 @@ module ts.server {
|
||||
|
||||
openClientFile(fileName: string) {
|
||||
var searchPath = ts.normalizePath(getDirectoryPath(fileName));
|
||||
var configFileName = ts.findConfigFile(searchPath);
|
||||
this.log("Search path: " + searchPath,"Info");
|
||||
var configFileName = this.findConfigFile(searchPath);
|
||||
if (configFileName) {
|
||||
this.log("Config file name: " + configFileName, "Info");
|
||||
} else {
|
||||
this.log("no config file");
|
||||
}
|
||||
if (configFileName) {
|
||||
configFileName = getAbsolutePath(configFileName, searchPath);
|
||||
}
|
||||
@@ -797,7 +823,6 @@ module ts.server {
|
||||
*/
|
||||
|
||||
closeClientFile(filename: string) {
|
||||
// TODO: tsconfig check
|
||||
var info = ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
if (info) {
|
||||
this.closeOpenFile(info);
|
||||
@@ -830,6 +855,9 @@ module ts.server {
|
||||
}
|
||||
|
||||
printProjects() {
|
||||
if (!this.psLogger.isVerbose()) {
|
||||
return;
|
||||
}
|
||||
this.psLogger.startGroup();
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
var project = this.inferredProjects[i];
|
||||
@@ -1440,6 +1468,10 @@ module ts.server {
|
||||
return accum;
|
||||
}
|
||||
|
||||
getLength(): number {
|
||||
return this.root.charCount();
|
||||
}
|
||||
|
||||
every(f: (ll: LineLeaf, s: number, len: number) => boolean, rangeStart: number, rangeEnd?: number) {
|
||||
if (!rangeEnd) {
|
||||
rangeEnd = this.root.charCount();
|
||||
|
||||
Vendored
+25
-1
@@ -405,6 +405,13 @@ declare module ts.server.protocol {
|
||||
arguments: OpenRequestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit request; value of command field is "exit". Ask the server process
|
||||
* to exit.
|
||||
*/
|
||||
export interface ExitRequest extends Request {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close request; value of command field is "close". Notify the
|
||||
* server that the client has closed a previously open file. If
|
||||
@@ -617,12 +624,29 @@ declare module ts.server.protocol {
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
/**
|
||||
* A string that is used for comparing completion items so that they can be ordered. This
|
||||
* is often the same as the name but may be different in certain circumstances.
|
||||
*/
|
||||
sortText: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional completion entry details, available on demand
|
||||
*/
|
||||
export interface CompletionEntryDetails extends CompletionEntry {
|
||||
export interface CompletionEntryDetails {
|
||||
/**
|
||||
* The symbol's name.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
/**
|
||||
* Display parts of the symbol (similar to quick info).
|
||||
*/
|
||||
|
||||
@@ -177,6 +177,12 @@ module ts.server {
|
||||
super(host, logger);
|
||||
}
|
||||
|
||||
exit() {
|
||||
this.projectService.log("Exiting...","Info");
|
||||
this.projectService.closeLog();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
listen() {
|
||||
rl.on('line',(input: string) => {
|
||||
var message = input.trim();
|
||||
@@ -184,9 +190,7 @@ module ts.server {
|
||||
});
|
||||
|
||||
rl.on('close',() => {
|
||||
this.projectService.log("Exiting...");
|
||||
this.projectService.closeLog();
|
||||
process.exit(0);
|
||||
this.exit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+11
-2
@@ -76,13 +76,14 @@ module ts.server {
|
||||
}
|
||||
|
||||
export module CommandNames {
|
||||
export var Brace = "brace";
|
||||
export var Change = "change";
|
||||
export var Close = "close";
|
||||
export var Completions = "completions";
|
||||
export var CompletionDetails = "completionEntryDetails";
|
||||
export var SignatureHelp = "signatureHelp";
|
||||
export var Configure = "configure";
|
||||
export var Definition = "definition";
|
||||
export var Exit = "exit";
|
||||
export var Format = "format";
|
||||
export var Formatonkey = "formatonkey";
|
||||
export var Geterr = "geterr";
|
||||
@@ -94,7 +95,7 @@ module ts.server {
|
||||
export var Reload = "reload";
|
||||
export var Rename = "rename";
|
||||
export var Saveto = "saveto";
|
||||
export var Brace = "brace";
|
||||
export var SignatureHelp = "signatureHelp";
|
||||
export var Unknown = "unknown";
|
||||
}
|
||||
|
||||
@@ -758,6 +759,9 @@ module ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
exit() {
|
||||
}
|
||||
|
||||
onMessage(message: string) {
|
||||
if (this.logger.isVerbose()) {
|
||||
this.logger.info("request: " + message);
|
||||
@@ -769,6 +773,11 @@ module ts.server {
|
||||
var errorMessage: string;
|
||||
var responseRequired = true;
|
||||
switch (request.command) {
|
||||
case CommandNames.Exit: {
|
||||
this.exit();
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
case CommandNames.Definition: {
|
||||
var defArgs = <protocol.FileLocationRequestArgs>request.arguments;
|
||||
response = this.getDefinition(defArgs.line, defArgs.offset, defArgs.file);
|
||||
|
||||
@@ -22,7 +22,7 @@ module ts.NavigateTo {
|
||||
continue;
|
||||
}
|
||||
|
||||
// It was a match! If the pattern has dots in it, then also see if hte
|
||||
// It was a match! If the pattern has dots in it, then also see if the
|
||||
// declaration container matches as well.
|
||||
if (patternMatcher.patternContainsDots) {
|
||||
let containers = getContainers(declaration);
|
||||
|
||||
@@ -418,10 +418,10 @@ module ts.NavigationBar {
|
||||
}
|
||||
|
||||
function createFunctionItem(node: FunctionDeclaration) {
|
||||
if ((node.name || node.flags & NodeFlags.Default) && node.body && node.body.kind === SyntaxKind.Block) {
|
||||
if (node.body && node.body.kind === SyntaxKind.Block) {
|
||||
let childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
|
||||
|
||||
return getNavigationBarItem((!node.name && node.flags & NodeFlags.Default) ? "default": node.name.text ,
|
||||
return getNavigationBarItem(!node.name ? "default": node.name.text ,
|
||||
ts.ScriptElementKind.functionElement,
|
||||
getNodeModifiers(node),
|
||||
[getNodeSpan(node)],
|
||||
@@ -470,7 +470,7 @@ module ts.NavigationBar {
|
||||
childItems = getItemsWorker(sortNodes(nodes), createChildItem);
|
||||
}
|
||||
|
||||
var nodeName = !node.name && (node.flags & NodeFlags.Default) ? "default" : node.name.text;
|
||||
var nodeName = !node.name ? "default" : node.name.text;
|
||||
|
||||
return getNavigationBarItem(
|
||||
nodeName,
|
||||
|
||||
@@ -471,7 +471,7 @@ module ts {
|
||||
|
||||
// Helper function to compare two matches to determine which is better. Matches are first
|
||||
// ordered by kind (so all prefix matches always beat all substring matches). Then, if the
|
||||
// match is a camel case match, the relative weights of hte match are used to determine
|
||||
// match is a camel case match, the relative weights of the match are used to determine
|
||||
// which is better (with a greater weight being better). Then if the match is of the same
|
||||
// type, then a case sensitive match is considered better than an insensitive one.
|
||||
function patternMatchCompareTo(match1: PatternMatch, match2: PatternMatch): number {
|
||||
|
||||
+528
-173
@@ -730,7 +730,7 @@ module ts {
|
||||
public statements: NodeArray<Statement>;
|
||||
public endOfFileToken: Node;
|
||||
|
||||
public amdDependencies: {name: string; path: string}[];
|
||||
public amdDependencies: { name: string; path: string }[];
|
||||
public amdModuleName: string;
|
||||
public referencedFiles: FileReference[];
|
||||
|
||||
@@ -769,126 +769,131 @@ module ts {
|
||||
|
||||
public getNamedDeclarations() {
|
||||
if (!this.namedDeclarations) {
|
||||
let sourceFile = this;
|
||||
let namedDeclarations: Declaration[] = [];
|
||||
|
||||
forEachChild(sourceFile, function visit(node: Node): void {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
let functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
|
||||
if (functionDeclaration.name && functionDeclaration.name.getFullWidth() > 0) {
|
||||
let lastDeclaration = namedDeclarations.length > 0 ?
|
||||
namedDeclarations[namedDeclarations.length - 1] :
|
||||
undefined;
|
||||
|
||||
// Check whether this declaration belongs to an "overload group".
|
||||
if (lastDeclaration && functionDeclaration.symbol === lastDeclaration.symbol) {
|
||||
// Overwrite the last declaration if it was an overload
|
||||
// and this one is an implementation.
|
||||
if (functionDeclaration.body && !(<FunctionLikeDeclaration>lastDeclaration).body) {
|
||||
namedDeclarations[namedDeclarations.length - 1] = functionDeclaration;
|
||||
}
|
||||
}
|
||||
else {
|
||||
namedDeclarations.push(functionDeclaration);
|
||||
}
|
||||
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
if ((<Declaration>node).name) {
|
||||
namedDeclarations.push(<Declaration>node);
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
forEachChild(node, visit);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Block:
|
||||
if (isFunctionBlock(node)) {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// Only consider properties defined as constructor parameters
|
||||
if (!(node.flags & NodeFlags.AccessibilityModifier)) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
if (isBindingPattern((<VariableDeclaration>node).name)) {
|
||||
forEachChild((<VariableDeclaration>node).name, visit);
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
namedDeclarations.push(<Declaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
// Handle named exports case e.g.:
|
||||
// export {a, b as B} from "mod";
|
||||
if ((<ExportDeclaration>node).exportClause) {
|
||||
forEach((<ExportDeclaration>node).exportClause.elements, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
let importClause = (<ImportDeclaration>node).importClause;
|
||||
if (importClause) {
|
||||
// Handle default import case e.g.:
|
||||
// import d from "mod";
|
||||
if (importClause.name) {
|
||||
namedDeclarations.push(importClause);
|
||||
}
|
||||
|
||||
// Handle named bindings in imports e.g.:
|
||||
// import * as NS from "mod";
|
||||
// import {a, b as B} from "mod";
|
||||
if (importClause.namedBindings) {
|
||||
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
namedDeclarations.push(<NamespaceImport>importClause.namedBindings);
|
||||
}
|
||||
else {
|
||||
forEach((<NamedImports>importClause.namedBindings).elements, visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this.namedDeclarations = namedDeclarations;
|
||||
this.namedDeclarations = this.computeNamedDeclarations();
|
||||
}
|
||||
|
||||
return this.namedDeclarations;
|
||||
}
|
||||
|
||||
private computeNamedDeclarations() {
|
||||
let namedDeclarations: Declaration[] = [];
|
||||
|
||||
forEachChild(this, visit);
|
||||
|
||||
return namedDeclarations;
|
||||
|
||||
function visit(node: Node): void {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
let functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
|
||||
if (functionDeclaration.name && functionDeclaration.name.getFullWidth() > 0) {
|
||||
let lastDeclaration = namedDeclarations.length > 0 ?
|
||||
namedDeclarations[namedDeclarations.length - 1] :
|
||||
undefined;
|
||||
|
||||
// Check whether this declaration belongs to an "overload group".
|
||||
if (lastDeclaration && functionDeclaration.symbol === lastDeclaration.symbol) {
|
||||
// Overwrite the last declaration if it was an overload
|
||||
// and this one is an implementation.
|
||||
if (functionDeclaration.body && !(<FunctionLikeDeclaration>lastDeclaration).body) {
|
||||
namedDeclarations[namedDeclarations.length - 1] = functionDeclaration;
|
||||
}
|
||||
}
|
||||
else {
|
||||
namedDeclarations.push(functionDeclaration);
|
||||
}
|
||||
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
if ((<Declaration>node).name) {
|
||||
namedDeclarations.push(<Declaration>node);
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
forEachChild(node, visit);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Block:
|
||||
if (isFunctionBlock(node)) {
|
||||
forEachChild(node, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// Only consider properties defined as constructor parameters
|
||||
if (!(node.flags & NodeFlags.AccessibilityModifier)) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
if (isBindingPattern((<VariableDeclaration>node).name)) {
|
||||
forEachChild((<VariableDeclaration>node).name, visit);
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
namedDeclarations.push(<Declaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
// Handle named exports case e.g.:
|
||||
// export {a, b as B} from "mod";
|
||||
if ((<ExportDeclaration>node).exportClause) {
|
||||
forEach((<ExportDeclaration>node).exportClause.elements, visit);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
let importClause = (<ImportDeclaration>node).importClause;
|
||||
if (importClause) {
|
||||
// Handle default import case e.g.:
|
||||
// import d from "mod";
|
||||
if (importClause.name) {
|
||||
namedDeclarations.push(importClause);
|
||||
}
|
||||
|
||||
// Handle named bindings in imports e.g.:
|
||||
// import * as NS from "mod";
|
||||
// import {a, b as B} from "mod";
|
||||
if (importClause.namedBindings) {
|
||||
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||
namedDeclarations.push(<NamespaceImport>importClause.namedBindings);
|
||||
}
|
||||
else {
|
||||
forEach((<NamedImports>importClause.namedBindings).elements, visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1143,6 +1148,7 @@ module ts {
|
||||
name: string;
|
||||
kind: string; // see ScriptElementKind
|
||||
kindModifiers: string; // see ScriptElementKindModifier, comma separated
|
||||
sortText: string;
|
||||
}
|
||||
|
||||
export interface CompletionEntryDetails {
|
||||
@@ -1311,6 +1317,7 @@ module ts {
|
||||
// TODO: move these to enums
|
||||
export class ScriptElementKind {
|
||||
static unknown = "";
|
||||
static warning = "warning";
|
||||
|
||||
// predefined type (void) or keyword (class)
|
||||
static keyword = "keyword";
|
||||
@@ -1635,6 +1642,61 @@ module ts {
|
||||
sourceFile.scriptSnapshot = scriptSnapshot;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will compile source text from 'input' argument using specified compiler options.
|
||||
* If not options are provided - it will use a set of default compiler options.
|
||||
* Extra compiler options that will unconditionally be used bu this function are:
|
||||
* - separateCompilation = true
|
||||
* - allowNonTsExtensions = true
|
||||
*/
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string {
|
||||
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
|
||||
|
||||
options.separateCompilation = true;
|
||||
|
||||
// Filename can be non-ts file.
|
||||
options.allowNonTsExtensions = true;
|
||||
|
||||
// Parse
|
||||
var inputFileName = fileName || "module.ts";
|
||||
var sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
|
||||
// Store syntactic diagnostics
|
||||
if (diagnostics && sourceFile.parseDiagnostics) {
|
||||
diagnostics.push(...sourceFile.parseDiagnostics);
|
||||
}
|
||||
|
||||
// Output
|
||||
let outputText: string;
|
||||
|
||||
// Create a compilerHost object to allow the compiler to read and write files
|
||||
var compilerHost: CompilerHost = {
|
||||
getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined,
|
||||
writeFile: (name, text, writeByteOrderMark) => {
|
||||
Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
|
||||
outputText = text;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: () => "",
|
||||
getNewLine: () => (sys && sys.newLine) || "\r\n"
|
||||
};
|
||||
|
||||
var program = createProgram([inputFileName], options, compilerHost);
|
||||
|
||||
if (diagnostics) {
|
||||
diagnostics.push(...program.getGlobalDiagnostics());
|
||||
}
|
||||
|
||||
// Emit
|
||||
program.emit();
|
||||
|
||||
Debug.assert(outputText !== undefined, "Output generation failed");
|
||||
|
||||
return outputText;
|
||||
}
|
||||
|
||||
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile {
|
||||
let sourceFile = createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents);
|
||||
setSourceFileFields(sourceFile, scriptSnapshot, version);
|
||||
@@ -2106,7 +2168,8 @@ module ts {
|
||||
keywordCompletions.push({
|
||||
name: tokenToString(i),
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2370,15 +2433,26 @@ module ts {
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName));
|
||||
}
|
||||
|
||||
function isJavaScript(fileName: string) {
|
||||
return fileExtensionIs(fileName, ".js");
|
||||
}
|
||||
|
||||
/**
|
||||
* getSemanticDiagnostiscs return array of Diagnostics. If '-d' is not enabled, only report semantic errors
|
||||
* If '-d' enabled, report both semantic and emitter errors
|
||||
*/
|
||||
function getSemanticDiagnostics(fileName: string) {
|
||||
function getSemanticDiagnostics(fileName: string): Diagnostic[] {
|
||||
synchronizeHostData();
|
||||
|
||||
let targetSourceFile = getValidSourceFile(fileName);
|
||||
|
||||
// For JavaScript files, we don't want to report the normal typescript semantic errors.
|
||||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
if (isJavaScript(fileName)) {
|
||||
return getJavaScriptSemanticDiagnostics(targetSourceFile);
|
||||
}
|
||||
|
||||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
@@ -2392,27 +2466,199 @@ module ts {
|
||||
return concatenate(semanticDiagnostics, declarationDiagnostics);
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnostics(sourceFile: SourceFile): Diagnostic[] {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
|
||||
return diagnostics;
|
||||
|
||||
function walk(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
let classDeclaration = <ClassDeclaration>node;
|
||||
if (checkModifiers(classDeclaration.modifiers) ||
|
||||
checkTypeParameters(classDeclaration.typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
let functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
if (checkModifiers(functionDeclaration.modifiers) ||
|
||||
checkTypeParameters(functionDeclaration.typeParameters) ||
|
||||
checkTypeAnnotation(functionDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableStatement:
|
||||
let variableStatement = <VariableStatement>node;
|
||||
if (checkModifiers(variableStatement.modifiers)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
let variableDeclaration = <VariableDeclaration>node;
|
||||
if (checkTypeAnnotation(variableDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
let expression = <CallExpression>node;
|
||||
if (expression.typeArguments && expression.typeArguments.length > 0) {
|
||||
let start = expression.typeArguments.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, expression.typeArguments.end - start,
|
||||
Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
let parameter = <ParameterDeclaration>node;
|
||||
if (parameter.modifiers) {
|
||||
let start = parameter.modifiers.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, parameter.modifiers.end - start,
|
||||
Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.questionToken) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics.can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.type) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.Decorator:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.decorators_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return forEachChild(node, walk);
|
||||
}
|
||||
|
||||
function checkTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
|
||||
if (typeParameters) {
|
||||
let start = typeParameters.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, typeParameters.end - start, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkTypeAnnotation(type: TypeNode): boolean {
|
||||
if (type) {
|
||||
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: ModifiersArray): boolean {
|
||||
if (modifiers) {
|
||||
for (let modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getGlobalDiagnostics();
|
||||
}
|
||||
|
||||
/// Completion
|
||||
function getCompletionEntryDisplayName(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
let displayName = symbol.getName();
|
||||
if (displayName) {
|
||||
// If this is the default export, get the name of the declaration if it exists
|
||||
if (displayName === "default") {
|
||||
let localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol && localSymbol.name) {
|
||||
displayName = symbol.valueDeclaration.localSymbol.name;
|
||||
}
|
||||
}
|
||||
|
||||
let firstCharCode = displayName.charCodeAt(0);
|
||||
// First check of the displayName is not external module; if it is an external module, it is not valid entry
|
||||
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the symbol is external module, don't show it in the completion list
|
||||
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return getCompletionEntryDisplayName(displayName, target, performCharacterChecks);
|
||||
}
|
||||
|
||||
function getCompletionEntryDisplayName(displayName: string, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
if (!displayName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let firstCharCode = displayName.charCodeAt(0);
|
||||
// First check of the displayName is not external module; if it is an external module, it is not valid entry
|
||||
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the symbol is external module, don't show it in the completion list
|
||||
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
|
||||
if (displayName.length >= 2 &&
|
||||
firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
|
||||
(firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
|
||||
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
|
||||
@@ -2442,19 +2688,24 @@ module ts {
|
||||
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
|
||||
// We would like to only show things that can be added after a dot, so for instance numeric properties can
|
||||
// not be accessed with a dot (a.1 <- invalid)
|
||||
let displayName = getCompletionEntryDisplayName(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true);
|
||||
let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true);
|
||||
if (!displayName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// TODO(drosen): Right now we just permit *all* semantic meanings when calling 'getSymbolKind'
|
||||
// which is permissible given that it is backwards compatible; but really we should consider
|
||||
// passing the meaning for the node so that we don't report that a suggestion for a value is an interface.
|
||||
// We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration.
|
||||
// TODO(drosen): Right now we just permit *all* semantic meanings when calling
|
||||
// 'getSymbolKind' which is permissible given that it is backwards compatible; but
|
||||
// really we should consider passing the meaning for the node so that we don't report
|
||||
// that a suggestion for a value is an interface. We COULD also just do what
|
||||
// 'getSymbolModifiers' does, which is to use the first declaration.
|
||||
|
||||
// Use a 'sortText' of 0' so that all symbol completion entries come before any other
|
||||
// entries (like JavaScript identifier entries).
|
||||
return {
|
||||
name: displayName,
|
||||
kind: getSymbolKind(symbol, typeChecker, location),
|
||||
kindModifiers: getSymbolModifiers(symbol)
|
||||
kindModifiers: getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2498,8 +2749,9 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Find the node where completion is requested on, in the case of a completion after a dot, it is the member access expression
|
||||
// otherwise, it is a request for all visible symbols in the scope, and the node is the current location
|
||||
// Find the node where completion is requested on, in the case of a completion after
|
||||
// a dot, it is the member access expression other wise, it is a request for all
|
||||
// visible symbols in the scope, and the node is the current location.
|
||||
let node = currentToken;
|
||||
let isRightOfDot = false;
|
||||
if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
@@ -2517,11 +2769,26 @@ module ts {
|
||||
let semanticStart = new Date().getTime();
|
||||
let isMemberCompletion: boolean;
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let symbols: Symbol[];
|
||||
let symbols: Symbol[] = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
getTypeScriptMemberSymbols();
|
||||
}
|
||||
else {
|
||||
// For JavaScript or TypeScript, if we're not after a dot, then just try to get the
|
||||
// global symbols in scope. These results should be valid for either language as
|
||||
// the set of symbols that can be referenced from this location.
|
||||
if (!tryGetGlobalSymbols()) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
|
||||
|
||||
return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
symbols = [];
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
|
||||
@@ -2535,7 +2802,8 @@ module ts {
|
||||
|
||||
if (symbol && symbol.flags & SymbolFlags.HasExports) {
|
||||
// Extract module or enum members
|
||||
forEachValue(symbol.exports, symbol => {
|
||||
let exportedSymbols = typeInfoResolver.getExportsOfModule(symbol);
|
||||
forEach(exportedSymbols, symbol => {
|
||||
if (typeInfoResolver.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name)) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
@@ -2553,7 +2821,8 @@ module ts {
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
function tryGetGlobalSymbols(): boolean {
|
||||
let containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(contextToken);
|
||||
if (containingObjectLiteral) {
|
||||
// Object literal expression, look up possible property names from contextual type
|
||||
@@ -2562,7 +2831,7 @@ module ts {
|
||||
|
||||
let contextualType = typeInfoResolver.getContextualType(containingObjectLiteral);
|
||||
if (!contextualType) {
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
|
||||
let contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType);
|
||||
@@ -2579,8 +2848,17 @@ module ts {
|
||||
if (showCompletionsInImportsClause(contextToken)) {
|
||||
let importDeclaration = <ImportDeclaration>getAncestor(contextToken, SyntaxKind.ImportDeclaration);
|
||||
Debug.assert(importDeclaration !== undefined);
|
||||
let exports = typeInfoResolver.getExportsOfExternalModule(importDeclaration);
|
||||
symbols = filterModuleExports(exports, importDeclaration);
|
||||
|
||||
let exports: Symbol[];
|
||||
if (importDeclaration.moduleSpecifier) {
|
||||
let moduleSpecifierSymbol = typeInfoResolver.getSymbolAtLocation(importDeclaration.moduleSpecifier);
|
||||
if (moduleSpecifierSymbol) {
|
||||
exports = typeInfoResolver.getExportsOfModule(moduleSpecifierSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
//let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
|
||||
symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2620,18 +2898,16 @@ module ts {
|
||||
previousToken.getStart() :
|
||||
position;
|
||||
|
||||
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile);
|
||||
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
|
||||
|
||||
/// TODO filter meaning based on the current context
|
||||
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
symbols = typeInfoResolver.getSymbolsInScope(scopeNode, symbolMeanings);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
|
||||
|
||||
return { symbols, isMemberCompletion, isNewIdentifierLocation, location };
|
||||
|
||||
/**
|
||||
* Finds the first node that "embraces" the position, so that one may
|
||||
* accurately aggregate locals from the closest containing scope.
|
||||
@@ -2932,18 +3208,26 @@ module ts {
|
||||
|
||||
function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo {
|
||||
synchronizeHostData();
|
||||
|
||||
|
||||
let completionData = getCompletionData(fileName, position);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let { symbols, isMemberCompletion, isNewIdentifierLocation, location } = completionData;
|
||||
if (!symbols || symbols.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot } = completionData;
|
||||
|
||||
var entries = getCompletionEntriesFromSymbols(symbols);
|
||||
let entries: CompletionEntry[];
|
||||
if (isRightOfDot && isJavaScript(fileName)) {
|
||||
entries = getCompletionEntriesFromSymbols(symbols);
|
||||
addRange(entries, getJavaScriptCompletionEntries());
|
||||
}
|
||||
else {
|
||||
if (!symbols || symbols.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
entries = getCompletionEntriesFromSymbols(symbols);
|
||||
}
|
||||
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion) {
|
||||
@@ -2952,21 +3236,51 @@ module ts {
|
||||
|
||||
return { isMemberCompletion, isNewIdentifierLocation, entries };
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[]): CompletionEntry[] {
|
||||
let start = new Date().getTime();
|
||||
var entries: CompletionEntry[] = [];
|
||||
var nameToSymbol: Map<Symbol> = {};
|
||||
function getJavaScriptCompletionEntries(): CompletionEntry[] {
|
||||
let entries: CompletionEntry[] = [];
|
||||
let allNames: Map<string> = {};
|
||||
let target = program.getCompilerOptions().target;
|
||||
|
||||
for (let symbol of symbols) {
|
||||
let entry = createCompletionEntry(symbol, typeInfoResolver, location);
|
||||
if (entry) {
|
||||
let id = escapeIdentifier(entry.name);
|
||||
if (!lookUp(nameToSymbol, id)) {
|
||||
entries.push(entry);
|
||||
nameToSymbol[id] = symbol;
|
||||
for (let sourceFile of program.getSourceFiles()) {
|
||||
let nameTable = getNameTable(sourceFile);
|
||||
for (let name in nameTable) {
|
||||
if (!allNames[name]) {
|
||||
allNames[name] = name;
|
||||
let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true);
|
||||
if (displayName) {
|
||||
let entry = {
|
||||
name: displayName,
|
||||
kind: ScriptElementKind.warning,
|
||||
kindModifiers: "",
|
||||
sortText: "1"
|
||||
};
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[]): CompletionEntry[] {
|
||||
let start = new Date().getTime();
|
||||
var entries: CompletionEntry[] = [];
|
||||
|
||||
if (symbols) {
|
||||
var nameToSymbol: Map<Symbol> = {};
|
||||
for (let symbol of symbols) {
|
||||
let entry = createCompletionEntry(symbol, typeInfoResolver, location);
|
||||
if (entry) {
|
||||
let id = escapeIdentifier(entry.name);
|
||||
if (!lookUp(nameToSymbol, id)) {
|
||||
entries.push(entry);
|
||||
nameToSymbol[id] = symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
|
||||
return entries;
|
||||
}
|
||||
@@ -2985,7 +3299,7 @@ module ts {
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
let symbol = forEach(symbols, s => getCompletionEntryDisplayName(s, target, /*performCharacterChecks:*/ false) === entryName ? s : undefined);
|
||||
let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false) === entryName ? s : undefined);
|
||||
|
||||
if (symbol) {
|
||||
let displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, typeInfoResolver, location, SemanticMeaning.All);
|
||||
@@ -3641,8 +3955,24 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
/// References and Occurrences
|
||||
function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
|
||||
let results = getOccurrencesAtPositionCore(fileName, position);
|
||||
|
||||
if (results) {
|
||||
let sourceFile = getCanonicalFileName(normalizeSlashes(fileName));
|
||||
|
||||
// ensure the results are in the file we're interested in
|
||||
results.forEach((value) => {
|
||||
let targetFile = getCanonicalFileName(normalizeSlashes(value.fileName));
|
||||
Debug.assert(sourceFile == targetFile, `Unexpected file in results. Found results in ${targetFile} expected only results in ${sourceFile}.`);
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// References and Occurrences
|
||||
function getOccurrencesAtPositionCore(fileName: string, position: number): ReferenceEntry[] {
|
||||
synchronizeHostData();
|
||||
|
||||
let sourceFile = getValidSourceFile(fileName);
|
||||
@@ -4877,8 +5207,8 @@ module ts {
|
||||
if (symbol && symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
forEach(symbol.getDeclarations(), declaration => {
|
||||
if (declaration.kind === SyntaxKind.ClassDeclaration) {
|
||||
getPropertySymbolFromTypeReference(getClassBaseTypeNode(<ClassDeclaration>declaration));
|
||||
forEach(getClassImplementedTypeNodes(<ClassDeclaration>declaration), getPropertySymbolFromTypeReference);
|
||||
getPropertySymbolFromTypeReference(getClassExtendsHeritageClauseElement(<ClassDeclaration>declaration));
|
||||
forEach(getClassImplementsHeritageClauseElements(<ClassDeclaration>declaration), getPropertySymbolFromTypeReference);
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.InterfaceDeclaration) {
|
||||
forEach(getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration), getPropertySymbolFromTypeReference);
|
||||
@@ -4887,7 +5217,7 @@ module ts {
|
||||
}
|
||||
return;
|
||||
|
||||
function getPropertySymbolFromTypeReference(typeReference: TypeReferenceNode) {
|
||||
function getPropertySymbolFromTypeReference(typeReference: HeritageClauseElement) {
|
||||
if (typeReference) {
|
||||
let type = typeInfoResolver.getTypeAtLocation(typeReference);
|
||||
if (type) {
|
||||
@@ -5144,19 +5474,44 @@ module ts {
|
||||
}
|
||||
|
||||
function isTypeReference(node: Node): boolean {
|
||||
if (isRightSideOfQualifiedName(node)) {
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(node) ) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeReference;
|
||||
return node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.HeritageClauseElement;
|
||||
}
|
||||
|
||||
function isNamespaceReference(node: Node): boolean {
|
||||
return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node);
|
||||
}
|
||||
|
||||
function isPropertyAccessNamespaceReference(node: Node): boolean {
|
||||
let root = node;
|
||||
let isLastClause = true;
|
||||
if (root.parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
while (root.parent && root.parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
root = root.parent;
|
||||
}
|
||||
|
||||
isLastClause = (<PropertyAccessExpression>root).name === node;
|
||||
}
|
||||
|
||||
if (!isLastClause && root.parent.kind === SyntaxKind.HeritageClauseElement && root.parent.parent.kind === SyntaxKind.HeritageClause) {
|
||||
let decl = root.parent.parent.parent;
|
||||
return (decl.kind === SyntaxKind.ClassDeclaration && (<HeritageClause>root.parent.parent).token === SyntaxKind.ImplementsKeyword) ||
|
||||
(decl.kind === SyntaxKind.InterfaceDeclaration && (<HeritageClause>root.parent.parent).token === SyntaxKind.ExtendsKeyword);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isQualifiedNameNamespaceReference(node: Node): boolean {
|
||||
let root = node;
|
||||
let isLastClause = true;
|
||||
if (root.parent.kind === SyntaxKind.QualifiedName) {
|
||||
while (root.parent && root.parent.kind === SyntaxKind.QualifiedName)
|
||||
while (root.parent && root.parent.kind === SyntaxKind.QualifiedName) {
|
||||
root = root.parent;
|
||||
}
|
||||
|
||||
isLastClause = (<QualifiedName>root).right === node;
|
||||
}
|
||||
|
||||
+17
-12
@@ -331,6 +331,22 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; } []{
|
||||
return diagnostics.map(d => realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
|
||||
return {
|
||||
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
/// TODO: no need for the tolowerCase call
|
||||
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
|
||||
code: diagnostic.code
|
||||
};
|
||||
}
|
||||
|
||||
class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim {
|
||||
private logger: Logger;
|
||||
|
||||
@@ -391,18 +407,7 @@ module ts {
|
||||
|
||||
private realizeDiagnostics(diagnostics: Diagnostic[]): { message: string; start: number; length: number; category: string; }[]{
|
||||
var newLine = this.getNewLine();
|
||||
return diagnostics.map(d => this.realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
private realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
|
||||
return {
|
||||
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
/// TODO: no need for the tolowerCase call
|
||||
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
|
||||
code: diagnostic.code
|
||||
};
|
||||
return ts.realizeDiagnostics(diagnostics, newLine);
|
||||
}
|
||||
|
||||
public getSyntacticClassifications(fileName: string, start: number, length: number): string {
|
||||
|
||||
Reference in New Issue
Block a user