mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fixDeFaultOfFindAllRefsToMaster
Conflicts: src/compiler/checker.ts src/compiler/types.ts
This commit is contained in:
+291
-13
@@ -1,7 +1,7 @@
|
||||
/// <reference path="parser.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export let bindTime = 0;
|
||||
|
||||
export const enum ModuleInstanceState {
|
||||
@@ -88,12 +88,20 @@ module ts {
|
||||
let container: Node;
|
||||
let blockScopeContainer: Node;
|
||||
let lastContainer: Node;
|
||||
|
||||
// If this file is an external module, then it is automatically in strict-mode according to
|
||||
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
|
||||
// not depending on if we see "use strict" in certain places (or if we hit a class/namespace).
|
||||
let inStrictMode = !!file.externalModuleIndicator;
|
||||
|
||||
let symbolCount = 0;
|
||||
let Symbol = objectAllocator.getSymbolConstructor();
|
||||
let classifiableNames: Map<string> = {};
|
||||
|
||||
if (!file.locals) {
|
||||
bind(file);
|
||||
file.symbolCount = symbolCount;
|
||||
file.classifiableNames = classifiableNames;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -194,6 +202,11 @@ module ts {
|
||||
symbol = hasProperty(symbolTable, name)
|
||||
? symbolTable[name]
|
||||
: (symbolTable[name] = createSymbol(SymbolFlags.None, name));
|
||||
|
||||
if (name && (includes & SymbolFlags.Classifiable)) {
|
||||
classifiableNames[name] = name;
|
||||
}
|
||||
|
||||
if (symbol.flags & excludes) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
@@ -338,6 +351,7 @@ module ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return ContainerFlags.IsContainerWithLocals;
|
||||
|
||||
case SyntaxKind.CatchClause:
|
||||
@@ -385,10 +399,10 @@ module ts {
|
||||
|
||||
function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
|
||||
switch (container.kind) {
|
||||
// Modules, source files, and classes need specialized handling for how their
|
||||
// Modules, source files, and classes need specialized handling for how their
|
||||
// members are declared (for example, a member of a class will go into a specific
|
||||
// symbol table depending on if it is static or not). As such, we defer to
|
||||
// specialized handlers to take care of declaring these child members.
|
||||
// symbol table depending on if it is static or not). We defer to specialized
|
||||
// handlers to take care of declaring these child members.
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return declareModuleMember(node, symbolFlags, symbolExcludes);
|
||||
|
||||
@@ -406,9 +420,10 @@ module ts {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
// Interface/Object-types always have their children added to the 'members' of
|
||||
// their container. They are only accessible through an instance of their
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
// object / type / interface declaring them).
|
||||
// their container. They are only accessible through an instance of their
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
// object / type / interface declaring them). An exception is type parameters,
|
||||
// which are in scope without qualification (similar to 'locals').
|
||||
return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
|
||||
case SyntaxKind.FunctionType:
|
||||
@@ -424,11 +439,12 @@ module ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// All the children of these container types are never visible through another
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
// they're only accessed 'lexically' (i.e. from code that exists underneath
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
// they're only accessed 'lexically' (i.e. from code that exists underneath
|
||||
// their container in the tree. To accomplish this, we simply add their declared
|
||||
// symbol to the 'locals' of the container. These symbols can then be found as
|
||||
// symbol to the 'locals' of the container. These symbols can then be found as
|
||||
// the type checker walks up the containers, checking them for matching names.
|
||||
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
@@ -521,6 +537,51 @@ module ts {
|
||||
typeLiteralSymbol.members = { [symbol.name]: symbol };
|
||||
}
|
||||
|
||||
function bindObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
const enum ElementKind {
|
||||
Property = 1,
|
||||
Accessor = 2
|
||||
}
|
||||
|
||||
if (inStrictMode) {
|
||||
let seen: Map<ElementKind> = {};
|
||||
|
||||
for (let prop of node.properties) {
|
||||
if (prop.name.kind !== SyntaxKind.Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let identifier = <Identifier>prop.name;
|
||||
|
||||
// ECMA-262 11.1.5 Object Initialiser
|
||||
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
|
||||
// a.This production is contained in strict code and IsDataDescriptor(previous) is true and
|
||||
// IsDataDescriptor(propId.descriptor) is true.
|
||||
// b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
|
||||
// c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
|
||||
// d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
|
||||
// and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
|
||||
let currentKind = prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.MethodDeclaration
|
||||
? ElementKind.Property
|
||||
: ElementKind.Accessor;
|
||||
|
||||
let existingKind = seen[identifier.text];
|
||||
if (!existingKind) {
|
||||
seen[identifier.text] = currentKind;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentKind === ElementKind.Property && existingKind === ElementKind.Property) {
|
||||
let span = getErrorSpanForNode(file, identifier);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||
Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||
let symbol = createSymbol(symbolFlags, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||
@@ -550,6 +611,138 @@ module ts {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
|
||||
// check for reserved words used as identifiers in strict mode code.
|
||||
function checkStrictModeIdentifier(node: Identifier) {
|
||||
if (inStrictMode &&
|
||||
node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
|
||||
node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord &&
|
||||
!isIdentifierName(node)) {
|
||||
|
||||
// Report error only if there are no parse errors in file
|
||||
if (!file.parseDiagnostics.length) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node,
|
||||
getStrictModeIdentifierMessage(node), declarationNameToString(node)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStrictModeIdentifierMessage(node: Node) {
|
||||
// Provide specialized messages to help the user understand why we think they're in
|
||||
// strict mode.
|
||||
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
|
||||
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
|
||||
}
|
||||
|
||||
if (file.externalModuleIndicator) {
|
||||
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
|
||||
}
|
||||
|
||||
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
|
||||
}
|
||||
|
||||
function checkStrictModeBinaryExpression(node: BinaryExpression) {
|
||||
if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
|
||||
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
// Assignment operator(11.13) or of a PostfixExpression(11.3)
|
||||
checkStrictModeEvalOrArguments(node, <Identifier>node.left);
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModeCatchClause(node: CatchClause) {
|
||||
// It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
|
||||
// Catch production is eval or arguments
|
||||
if (inStrictMode && node.variableDeclaration) {
|
||||
checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModeDeleteExpression(node: DeleteExpression) {
|
||||
// Grammar checking
|
||||
if (inStrictMode && node.expression.kind === SyntaxKind.Identifier) {
|
||||
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
|
||||
// UnaryExpression is a direct reference to a variable, function argument, or function name
|
||||
let span = getErrorSpanForNode(file, node.expression);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
|
||||
}
|
||||
}
|
||||
|
||||
function isEvalOrArgumentsIdentifier(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.Identifier &&
|
||||
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
|
||||
}
|
||||
|
||||
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
|
||||
if (name && name.kind === SyntaxKind.Identifier) {
|
||||
let identifier = <Identifier>name;
|
||||
if (isEvalOrArgumentsIdentifier(identifier)) {
|
||||
// We check first if the name is inside class declaration or class expression; if so give explicit message
|
||||
// otherwise report generic error message.
|
||||
let span = getErrorSpanForNode(file, name);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStrictModeEvalOrArgumentsMessage(node: Node) {
|
||||
// Provide specialized messages to help the user understand why we think they're in
|
||||
// strict mode.
|
||||
if (getAncestor(node, SyntaxKind.ClassDeclaration) || getAncestor(node, SyntaxKind.ClassExpression)) {
|
||||
return Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
|
||||
}
|
||||
|
||||
if (file.externalModuleIndicator) {
|
||||
return Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
|
||||
}
|
||||
|
||||
return Diagnostics.Invalid_use_of_0_in_strict_mode;
|
||||
}
|
||||
|
||||
function checkStrictModeFunctionName(node: FunctionLikeDeclaration) {
|
||||
if (inStrictMode) {
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
|
||||
checkStrictModeEvalOrArguments(node, node.name);
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModeNumericLiteral(node: LiteralExpression) {
|
||||
if (inStrictMode && node.flags & NodeFlags.OctalLiteral) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModePostfixUnaryExpression(node: PostfixUnaryExpression) {
|
||||
// Grammar checking
|
||||
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
|
||||
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
|
||||
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
|
||||
if (inStrictMode) {
|
||||
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModePrefixUnaryExpression(node: PrefixUnaryExpression) {
|
||||
// Grammar checking
|
||||
if (inStrictMode) {
|
||||
if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) {
|
||||
checkStrictModeEvalOrArguments(node, <Identifier>node.operand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkStrictModeWithStatement(node: WithStatement) {
|
||||
// Grammar checking for withStatement
|
||||
if (inStrictMode) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_strict_mode);
|
||||
}
|
||||
}
|
||||
|
||||
function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) {
|
||||
let span = getSpanOfTokenAtPosition(file, node.pos);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
||||
}
|
||||
|
||||
function getDestructuringParameterName(node: Declaration) {
|
||||
return "__" + indexOf((<SignatureDeclaration>node.parent).parameters, node);
|
||||
}
|
||||
@@ -557,6 +750,11 @@ module ts {
|
||||
function bind(node: Node) {
|
||||
node.parent = parent;
|
||||
|
||||
var savedInStrictMode = inStrictMode;
|
||||
if (!savedInStrictMode) {
|
||||
updateStrictMode(node);
|
||||
}
|
||||
|
||||
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
||||
// and then potentially add the symbol to an appropriate symbol table. Possible
|
||||
// destination symbol tables are:
|
||||
@@ -574,10 +772,70 @@ module ts {
|
||||
// the current 'container' node when it changes. This helps us know which symbol table
|
||||
// a local should go into for example.
|
||||
bindChildren(node);
|
||||
|
||||
inStrictMode = savedInStrictMode;
|
||||
}
|
||||
|
||||
function updateStrictMode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
updateStrictModeStatementList((<SourceFile | ModuleBlock>node).statements);
|
||||
return;
|
||||
case SyntaxKind.Block:
|
||||
if (isFunctionLike(node.parent)) {
|
||||
updateStrictModeStatementList((<Block>node).statements);
|
||||
}
|
||||
return;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
// All classes are automatically in strict mode in ES6.
|
||||
inStrictMode = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
||||
for (let statement of statements) {
|
||||
if (!isPrologueDirective(statement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUseStrictPrologueDirective(<ExpressionStatement>statement)) {
|
||||
inStrictMode = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Should be called only on prologue directives (isPrologueDirective(node) should be true)
|
||||
function isUseStrictPrologueDirective(node: ExpressionStatement): boolean {
|
||||
let nodeText = getTextOfNodeFromSourceText(file.text, node.expression);
|
||||
|
||||
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
|
||||
// string to contain unicode escapes (as per ES5).
|
||||
return nodeText === '"use strict"' || nodeText === "'use strict'";
|
||||
}
|
||||
|
||||
function bindWorker(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return checkStrictModeIdentifier(<Identifier>node);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return checkStrictModeBinaryExpression(<BinaryExpression>node);
|
||||
case SyntaxKind.CatchClause:
|
||||
return checkStrictModeCatchClause(<CatchClause>node);
|
||||
case SyntaxKind.DeleteExpression:
|
||||
return checkStrictModeDeleteExpression(<DeleteExpression>node);
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return checkStrictModeNumericLiteral(<LiteralExpression>node);
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
return checkStrictModePostfixUnaryExpression(<PostfixUnaryExpression>node);
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
|
||||
case SyntaxKind.WithStatement:
|
||||
return checkStrictModeWithStatement(<WithStatement>node);
|
||||
|
||||
case SyntaxKind.TypeParameter:
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
case SyntaxKind.Parameter:
|
||||
@@ -606,6 +864,7 @@ module ts {
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None),
|
||||
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
checkStrictModeFunctionName(<FunctionDeclaration>node);
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
|
||||
case SyntaxKind.Constructor:
|
||||
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None);
|
||||
@@ -619,9 +878,10 @@ module ts {
|
||||
case SyntaxKind.TypeLiteral:
|
||||
return bindAnonymousDeclaration(<TypeLiteralNode>node, SymbolFlags.TypeLiteral, "__type");
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return bindAnonymousDeclaration(<ObjectLiteralExpression>node, SymbolFlags.ObjectLiteral, "__object");
|
||||
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
checkStrictModeFunctionName(<FunctionExpression>node);
|
||||
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, "__function");
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
@@ -658,7 +918,11 @@ module ts {
|
||||
}
|
||||
|
||||
function bindExportAssignment(node: ExportAssignment) {
|
||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
if (!container.symbol || !container.symbol.exports) {
|
||||
// Export assignment in some sort of block construct
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
|
||||
}
|
||||
else if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
// An export default clause with an identifier exports all meanings of that identifier
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
|
||||
}
|
||||
@@ -669,7 +933,11 @@ module ts {
|
||||
}
|
||||
|
||||
function bindExportDeclaration(node: ExportDeclaration) {
|
||||
if (!node.exportClause) {
|
||||
if (!container.symbol || !container.symbol.exports) {
|
||||
// Export * in some sort of block construct
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node));
|
||||
}
|
||||
else if (!node.exportClause) {
|
||||
// All export * declarations are collected in an __export symbol
|
||||
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None);
|
||||
}
|
||||
@@ -719,6 +987,10 @@ module ts {
|
||||
}
|
||||
|
||||
function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) {
|
||||
if (inStrictMode) {
|
||||
checkStrictModeEvalOrArguments(node, node.name)
|
||||
}
|
||||
|
||||
if (!isBindingPattern(node.name)) {
|
||||
if (isBlockOrCatchScoped(node)) {
|
||||
bindBlockScopedVariableDeclaration(node);
|
||||
@@ -742,6 +1014,12 @@ module ts {
|
||||
}
|
||||
|
||||
function bindParameter(node: ParameterDeclaration) {
|
||||
if (inStrictMode) {
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
|
||||
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
|
||||
checkStrictModeEvalOrArguments(node, node.name);
|
||||
}
|
||||
|
||||
if (isBindingPattern(node.name)) {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node));
|
||||
}
|
||||
|
||||
+954
-847
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="scanner.ts"/>
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
/* @internal */
|
||||
export var optionDeclarations: CommandLineOption[] = [
|
||||
{
|
||||
@@ -103,9 +103,14 @@ module ts {
|
||||
name: "noResolve",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "skipDefaultLibCheck",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "out",
|
||||
type: "string",
|
||||
isFilePath: true,
|
||||
description: Diagnostics.Concatenate_and_emit_output_to_single_file,
|
||||
paramType: Diagnostics.FILE,
|
||||
},
|
||||
@@ -349,7 +354,7 @@ module ts {
|
||||
|
||||
return {
|
||||
options: getCompilerOptions(),
|
||||
fileNames: getFiles(),
|
||||
fileNames: getFileNames(),
|
||||
errors
|
||||
};
|
||||
|
||||
@@ -395,23 +400,24 @@ module ts {
|
||||
return options;
|
||||
}
|
||||
|
||||
function getFiles(): string[] {
|
||||
var files: string[] = [];
|
||||
function getFileNames(): string[] {
|
||||
var fileNames: string[] = [];
|
||||
if (hasProperty(json, "files")) {
|
||||
if (json["files"] instanceof Array) {
|
||||
var files = map(<string[]>json["files"], s => combinePaths(basePath, s));
|
||||
fileNames = map(<string[]>json["files"], s => combinePaths(basePath, s));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var sysFiles = host.readDirectory(basePath, ".ts");
|
||||
var exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
|
||||
var sysFiles = host.readDirectory(basePath, ".ts", exclude);
|
||||
for (var i = 0; i < sysFiles.length; i++) {
|
||||
var name = sysFiles[i];
|
||||
if (!fileExtensionIs(name, ".d.ts") || !contains(sysFiles, name.substr(0, name.length - 5) + ".ts")) {
|
||||
files.push(name);
|
||||
fileNames.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
return fileNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-2
@@ -1,7 +1,7 @@
|
||||
/// <reference path="types.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
// Ternary values are defined such that
|
||||
// x & y is False if either x or y is False.
|
||||
// x & y is Maybe if either x or y is Maybe, but neither x or y is False.
|
||||
@@ -15,6 +15,42 @@ module ts {
|
||||
True = -1
|
||||
}
|
||||
|
||||
export function createFileMap<T>(getCanonicalFileName: (fileName: string) => string): FileMap<T> {
|
||||
let files: Map<T> = {};
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
contains,
|
||||
remove,
|
||||
forEachValue: forEachValueInMap
|
||||
}
|
||||
|
||||
function set(fileName: string, value: T) {
|
||||
files[normalizeKey(fileName)] = value;
|
||||
}
|
||||
|
||||
function get(fileName: string) {
|
||||
return files[normalizeKey(fileName)];
|
||||
}
|
||||
|
||||
function contains(fileName: string) {
|
||||
return hasProperty(files, normalizeKey(fileName));
|
||||
}
|
||||
|
||||
function remove (fileName: string) {
|
||||
let key = normalizeKey(fileName);
|
||||
delete files[key];
|
||||
}
|
||||
|
||||
function forEachValueInMap(f: (value: T) => void) {
|
||||
forEachValue(files, f);
|
||||
}
|
||||
|
||||
function normalizeKey(key: string) {
|
||||
return getCanonicalFileName(normalizeSlashes(key));
|
||||
}
|
||||
}
|
||||
|
||||
export const enum Comparison {
|
||||
LessThan = -1,
|
||||
EqualTo = 0,
|
||||
@@ -536,7 +572,7 @@ module ts {
|
||||
export function getNormalizedPathComponents(path: string, currentDirectory: string) {
|
||||
path = normalizeSlashes(path);
|
||||
let rootLength = getRootLength(path);
|
||||
if (rootLength == 0) {
|
||||
if (rootLength === 0) {
|
||||
// If the path is not rooted it is relative to current directory
|
||||
path = combinePaths(normalizeSlashes(currentDirectory), path);
|
||||
rootLength = getRootLength(path);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="checker.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
interface ModuleElementDeclarationEmitInfo {
|
||||
node: Node;
|
||||
outputPos: number;
|
||||
@@ -709,7 +709,12 @@ module ts {
|
||||
function writeModuleDeclaration(node: ModuleDeclaration) {
|
||||
emitJsDocComments(node);
|
||||
emitModuleElementDeclarationFlags(node);
|
||||
write("module ");
|
||||
if (node.flags & NodeFlags.Namespace) {
|
||||
write("namespace ");
|
||||
}
|
||||
else {
|
||||
write("module ");
|
||||
}
|
||||
writeTextOfNode(currentSourceFile, node.name);
|
||||
while (node.body.kind !== SyntaxKind.ModuleBlock) {
|
||||
node = <ModuleDeclaration>node.body;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// <auto-generated />
|
||||
/// <reference path="types.ts" />
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export var Diagnostics = {
|
||||
Unterminated_string_literal: { code: 1002, category: DiagnosticCategory.Error, key: "Unterminated string literal." },
|
||||
Identifier_expected: { code: 1003, category: DiagnosticCategory.Error, key: "Identifier expected." },
|
||||
@@ -171,14 +171,26 @@ module ts {
|
||||
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" },
|
||||
Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" },
|
||||
Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1213, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." },
|
||||
Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" },
|
||||
Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." },
|
||||
Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: { code: 1214, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode." },
|
||||
Invalid_use_of_0_Modules_are_automatically_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Modules are automatically in strict mode." },
|
||||
Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." },
|
||||
Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." },
|
||||
Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." },
|
||||
Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." },
|
||||
An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." },
|
||||
_0_tag_already_specified: { code: 1223, category: DiagnosticCategory.Error, key: "'{0}' tag already specified." },
|
||||
Signature_0_must_have_a_type_predicate: { code: 1224, category: DiagnosticCategory.Error, key: "Signature '{0}' must have a type predicate." },
|
||||
Cannot_find_parameter_0: { code: 1225, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." },
|
||||
Type_predicate_0_is_not_assignable_to_1: { code: 1226, category: DiagnosticCategory.Error, key: "Type predicate '{0}' is not assignable to '{1}'." },
|
||||
Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1227, category: DiagnosticCategory.Error, key: "Parameter '{0}' is not in the same position as parameter '{1}'." },
|
||||
A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "A type predicate is only allowed in return type position for functions and methods." },
|
||||
A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." },
|
||||
A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "A type predicate cannot reference element '{0}' in a binding pattern." },
|
||||
An_export_assignment_can_only_be_used_in_a_module: { code: 1231, category: DiagnosticCategory.Error, key: "An export assignment can only be used in a module." },
|
||||
An_import_declaration_can_only_be_used_in_a_namespace_or_module: { code: 1232, category: DiagnosticCategory.Error, key: "An import declaration can only be used in a namespace or module." },
|
||||
An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." },
|
||||
An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." },
|
||||
A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." },
|
||||
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." },
|
||||
@@ -372,6 +384,11 @@ module ts {
|
||||
Cannot_find_namespace_0: { code: 2503, category: DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." },
|
||||
No_best_common_type_exists_among_yield_expressions: { code: 2504, category: DiagnosticCategory.Error, key: "No best common type exists among yield expressions." },
|
||||
A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." },
|
||||
_0_is_referenced_directly_or_indirectly_in_its_own_base_expression: { code: 2506, category: DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own base expression." },
|
||||
Type_0_is_not_a_constructor_function_type: { code: 2507, category: DiagnosticCategory.Error, key: "Type '{0}' is not a constructor function type." },
|
||||
No_base_constructor_has_the_specified_number_of_type_arguments: { code: 2508, category: DiagnosticCategory.Error, key: "No base constructor has the specified number of type arguments." },
|
||||
Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: DiagnosticCategory.Error, key: "Base constructor return type '{0}' is not a class or interface type." },
|
||||
Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: DiagnosticCategory.Error, key: "Base constructors must all have the same return type." },
|
||||
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}'." },
|
||||
|
||||
@@ -671,14 +671,14 @@
|
||||
"category": "Error",
|
||||
"code": 1213
|
||||
},
|
||||
"Type expected. '{0}' is a reserved word in strict mode": {
|
||||
"Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1214
|
||||
},
|
||||
"Invalid use of '{0}'. Modules are automatically in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1215
|
||||
},
|
||||
"Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1216
|
||||
},
|
||||
"Export assignment is not supported when '--module' flag is 'system'.": {
|
||||
"category": "Error",
|
||||
"code": 1218
|
||||
@@ -703,6 +703,55 @@
|
||||
"category": "Error",
|
||||
"code": 1223
|
||||
},
|
||||
"Signature '{0}' must have a type predicate.": {
|
||||
"category": "Error",
|
||||
"code": 1224
|
||||
},
|
||||
"Cannot find parameter '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 1225
|
||||
},
|
||||
"Type predicate '{0}' is not assignable to '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 1226
|
||||
},
|
||||
"Parameter '{0}' is not in the same position as parameter '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 1227
|
||||
},
|
||||
"A type predicate is only allowed in return type position for functions and methods.": {
|
||||
"category": "Error",
|
||||
"code": 1228
|
||||
},
|
||||
"A type predicate cannot reference a rest parameter.": {
|
||||
"category": "Error",
|
||||
"code": 1229
|
||||
},
|
||||
"A type predicate cannot reference element '{0}' in a binding pattern.": {
|
||||
"category": "Error",
|
||||
"code": 1230
|
||||
},
|
||||
"An export assignment can only be used in a module.": {
|
||||
"category": "Error",
|
||||
"code": 1231
|
||||
},
|
||||
"An import declaration can only be used in a namespace or module.": {
|
||||
"category": "Error",
|
||||
"code": 1232
|
||||
},
|
||||
"An export declaration can only be used in a module.": {
|
||||
"category": "Error",
|
||||
"code": 1233
|
||||
},
|
||||
"An ambient module declaration is only allowed at the top level in a file.": {
|
||||
"category": "Error",
|
||||
"code": 1234
|
||||
},
|
||||
"A namespace declaration is only allowed in a namespace or module.": {
|
||||
"category": "Error",
|
||||
"code": 1235
|
||||
},
|
||||
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1476,6 +1525,26 @@
|
||||
"category": "Error",
|
||||
"code": 2505
|
||||
},
|
||||
"'{0}' is referenced directly or indirectly in its own base expression.": {
|
||||
"category": "Error",
|
||||
"code": 2506
|
||||
},
|
||||
"Type '{0}' is not a constructor function type.": {
|
||||
"category": "Error",
|
||||
"code": 2507
|
||||
},
|
||||
"No base constructor has the specified number of type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2508
|
||||
},
|
||||
"Base constructor return type '{0}' is not a class or interface type.": {
|
||||
"category": "Error",
|
||||
"code": 2509
|
||||
},
|
||||
"Base constructors must all have the same return type.": {
|
||||
"category": "Error",
|
||||
"code": 2510
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
+215
-244
@@ -2,7 +2,7 @@
|
||||
/// <reference path="declarationEmitter.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) {
|
||||
return isExternalModule(sourceFile) || isDeclarationFile(sourceFile);
|
||||
}
|
||||
@@ -21,8 +21,7 @@ module ts {
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
__.prototype = b.prototype;
|
||||
d.prototype = new __();
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};`;
|
||||
|
||||
// emit output for the __decorate helper function
|
||||
@@ -125,7 +124,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
let generatedNameSet: Map<string> = {};
|
||||
let nodeToGeneratedName: string[] = [];
|
||||
let blockScopedVariableToGeneratedName: string[];
|
||||
let computedPropertyNamesToGeneratedNames: string[];
|
||||
|
||||
let extendsEmitted = false;
|
||||
@@ -249,81 +247,44 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
|
||||
function assignGeneratedName(node: Node, name: string) {
|
||||
nodeToGeneratedName[getNodeId(node)] = unescapeIdentifier(name);
|
||||
}
|
||||
|
||||
function generateNameForFunctionOrClassDeclaration(node: Declaration) {
|
||||
if (!node.name) {
|
||||
assignGeneratedName(node, makeUniqueName("default"));
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
|
||||
if (node.name.kind === SyntaxKind.Identifier) {
|
||||
let name = node.name.text;
|
||||
// Use module/enum name itself if it is unique, otherwise make a unique variation
|
||||
assignGeneratedName(node, isUniqueLocalName(name, node) ? name : makeUniqueName(name));
|
||||
}
|
||||
let name = node.name.text;
|
||||
// Use module/enum name itself if it is unique, otherwise make a unique variation
|
||||
return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
|
||||
}
|
||||
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
let expr = getExternalModuleName(node);
|
||||
let baseName = expr.kind === SyntaxKind.StringLiteral ?
|
||||
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
|
||||
assignGeneratedName(node, makeUniqueName(baseName));
|
||||
return makeUniqueName(baseName);
|
||||
}
|
||||
|
||||
function generateNameForImportDeclaration(node: ImportDeclaration) {
|
||||
if (node.importClause) {
|
||||
generateNameForImportOrExportDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForExportDeclaration(node: ExportDeclaration) {
|
||||
if (node.moduleSpecifier) {
|
||||
generateNameForImportOrExportDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForExportAssignment(node: ExportAssignment) {
|
||||
if (node.expression && node.expression.kind !== SyntaxKind.Identifier) {
|
||||
assignGeneratedName(node, makeUniqueName("default"));
|
||||
}
|
||||
function generateNameForExportDefault() {
|
||||
return makeUniqueName("default");
|
||||
}
|
||||
|
||||
function generateNameForNode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return makeUniqueName((<Identifier>node).text);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return generateNameForImportOrExportDeclaration(<ImportDeclaration | ExportDeclaration>node);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
generateNameForFunctionOrClassDeclaration(<Declaration>node);
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
generateNameForModuleOrEnum(<ModuleDeclaration>node);
|
||||
generateNameForNode((<ModuleDeclaration>node).body);
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
generateNameForModuleOrEnum(<EnumDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
generateNameForImportDeclaration(<ImportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
generateNameForExportDeclaration(<ExportDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
generateNameForExportAssignment(<ExportAssignment>node);
|
||||
break;
|
||||
return generateNameForExportDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function getGeneratedNameForNode(node: Node) {
|
||||
let nodeId = getNodeId(node);
|
||||
if (!nodeToGeneratedName[nodeId]) {
|
||||
generateNameForNode(node);
|
||||
}
|
||||
return nodeToGeneratedName[nodeId];
|
||||
let id = getNodeId(node);
|
||||
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateNameForNode(node)));
|
||||
}
|
||||
|
||||
function initializeEmitterWithSourceMaps() {
|
||||
@@ -358,7 +319,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
let prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
|
||||
// Line/Comma delimiters
|
||||
if (lastEncodedSourceMapSpan.emittedLine == lastRecordedSourceMapSpan.emittedLine) {
|
||||
if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
|
||||
// Emit comma to separate the entry
|
||||
if (sourceMapData.sourceMapMappings) {
|
||||
sourceMapData.sourceMapMappings += ",";
|
||||
@@ -441,8 +402,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
// If this location wasn't recorded or the location in source is going backwards, record the span
|
||||
if (!lastRecordedSourceMapSpan ||
|
||||
lastRecordedSourceMapSpan.emittedLine != emittedLine ||
|
||||
lastRecordedSourceMapSpan.emittedColumn != emittedColumn ||
|
||||
lastRecordedSourceMapSpan.emittedLine !== emittedLine ||
|
||||
lastRecordedSourceMapSpan.emittedColumn !== emittedColumn ||
|
||||
(lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
|
||||
(lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
|
||||
(lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
|
||||
@@ -687,19 +648,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
sourceMapDir = getDirectoryPath(normalizePath(jsFilePath));
|
||||
}
|
||||
|
||||
function emitNodeWithSourceMap(node: Node, allowGeneratedIdentifiers?: boolean) {
|
||||
function emitNodeWithSourceMap(node: Node) {
|
||||
if (node) {
|
||||
if (nodeIsSynthesized(node)) {
|
||||
return emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false);
|
||||
return emitNodeWithoutSourceMap(node);
|
||||
}
|
||||
if (node.kind != SyntaxKind.SourceFile) {
|
||||
if (node.kind !== SyntaxKind.SourceFile) {
|
||||
recordEmitNodeStartSpan(node);
|
||||
emitNodeWithoutSourceMap(node, allowGeneratedIdentifiers);
|
||||
emitNodeWithoutSourceMap(node);
|
||||
recordEmitNodeEndSpan(node);
|
||||
}
|
||||
else {
|
||||
recordNewSourceFileStart(<SourceFile>node);
|
||||
emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false);
|
||||
emitNodeWithoutSourceMap(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1201,80 +1162,129 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
|
||||
function isNotExpressionIdentifier(node: Identifier) {
|
||||
function isExpressionIdentifier(node: Node): boolean {
|
||||
let parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return (<Declaration>parent).name === node;
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
return (<ImportOrExportSpecifier>parent).name === node || (<ImportOrExportSpecifier>parent).propertyName === node;
|
||||
case SyntaxKind.BreakStatement:
|
||||
case SyntaxKind.ContinueStatement:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.Decorator:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return false;
|
||||
case SyntaxKind.LabeledStatement:
|
||||
return (<LabeledStatement>node.parent).label === node;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.TemplateSpan:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.YieldExpression:
|
||||
return true;
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return (<BindingElement | EnumMember | ParameterDeclaration | PropertyAssignment | PropertyDeclaration | VariableDeclaration>parent).initializer === node;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (<ExpressionStatement>parent).expression === node;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return (<FunctionLikeDeclaration>parent).body === node;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return (<ImportEqualsDeclaration>parent).moduleReference === node;
|
||||
case SyntaxKind.QualifiedName:
|
||||
return (<QualifiedName>parent).left === node;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function emitExpressionIdentifier(node: Identifier) {
|
||||
let substitution = resolver.getExpressionNameSubstitution(node, getGeneratedNameForNode);
|
||||
if (substitution) {
|
||||
write(substitution);
|
||||
let container = resolver.getReferencedExportContainer(node);
|
||||
if (container) {
|
||||
if (container.kind === SyntaxKind.SourceFile) {
|
||||
// Identifier references module export
|
||||
if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) {
|
||||
write("exports.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Identifier references namespace export
|
||||
write(getGeneratedNameForNode(container));
|
||||
write(".");
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node);
|
||||
}
|
||||
}
|
||||
|
||||
function getGeneratedNameForIdentifier(node: Identifier): string {
|
||||
if (nodeIsSynthesized(node) || !blockScopedVariableToGeneratedName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var variableId = resolver.getBlockScopedVariableId(node)
|
||||
if (variableId === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return blockScopedVariableToGeneratedName[variableId];
|
||||
}
|
||||
|
||||
function emitIdentifier(node: Identifier, allowGeneratedIdentifiers: boolean) {
|
||||
if (allowGeneratedIdentifiers) {
|
||||
let generatedName = getGeneratedNameForIdentifier(node);
|
||||
if (generatedName) {
|
||||
write(generatedName);
|
||||
else if (languageVersion < ScriptTarget.ES6) {
|
||||
let declaration = resolver.getReferencedImportDeclaration(node);
|
||||
if (declaration) {
|
||||
if (declaration.kind === SyntaxKind.ImportClause) {
|
||||
// Identifier references default import
|
||||
write(getGeneratedNameForNode(<ImportDeclaration>declaration.parent));
|
||||
write(languageVersion === ScriptTarget.ES3 ? '["default"]' : ".default");
|
||||
return;
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.ImportSpecifier) {
|
||||
// Identifier references named import
|
||||
write(getGeneratedNameForNode(<ImportDeclaration>declaration.parent.parent.parent));
|
||||
write(".");
|
||||
writeTextOfNode(currentSourceFile, (<ImportSpecifier>declaration).propertyName || (<ImportSpecifier>declaration).name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
declaration = resolver.getReferencedNestedRedeclaration(node);
|
||||
if (declaration) {
|
||||
write(getGeneratedNameForNode(declaration.name));
|
||||
return;
|
||||
}
|
||||
}
|
||||
writeTextOfNode(currentSourceFile, node);
|
||||
}
|
||||
|
||||
function isNameOfNestedRedeclaration(node: Identifier) {
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
let parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return (<Declaration>parent).name === node && resolver.isNestedRedeclaration(<Declaration>parent);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function emitIdentifier(node: Identifier) {
|
||||
if (!node.parent) {
|
||||
write(node.text);
|
||||
}
|
||||
else if (!isNotExpressionIdentifier(node)) {
|
||||
else if (isExpressionIdentifier(node)) {
|
||||
emitExpressionIdentifier(node);
|
||||
}
|
||||
else if (isNameOfNestedRedeclaration(node)) {
|
||||
write(getGeneratedNameForNode(node));
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentSourceFile, node);
|
||||
}
|
||||
@@ -1320,7 +1330,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
function emitBindingElement(node: BindingElement) {
|
||||
if (node.propertyName) {
|
||||
emit(node.propertyName, /*allowGeneratedIdentifiers*/ false);
|
||||
emit(node.propertyName);
|
||||
write(": ");
|
||||
}
|
||||
if (node.dotDotDotToken) {
|
||||
@@ -1646,6 +1656,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
function parenthesizeForAccess(expr: Expression): LeftHandSideExpression {
|
||||
// When diagnosing whether the expression needs parentheses, the decision should be based
|
||||
// on the innermost expression in a chain of nested type assertions.
|
||||
while (expr.kind === SyntaxKind.TypeAssertionExpression) {
|
||||
expr = (<TypeAssertion>expr).expression;
|
||||
}
|
||||
|
||||
// isLeftHandSideExpression is almost the correct criterion for when it is not necessary
|
||||
// to parenthesize the expression before a dot. The known exceptions are:
|
||||
//
|
||||
@@ -1654,7 +1670,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
// NumberLiteral
|
||||
// 1.x -> not the same as (1).x
|
||||
//
|
||||
if (isLeftHandSideExpression(expr) && expr.kind !== SyntaxKind.NewExpression && expr.kind !== SyntaxKind.NumericLiteral) {
|
||||
if (isLeftHandSideExpression(expr) &&
|
||||
expr.kind !== SyntaxKind.NewExpression &&
|
||||
expr.kind !== SyntaxKind.NumericLiteral) {
|
||||
|
||||
return <LeftHandSideExpression>expr;
|
||||
}
|
||||
let node = <ParenthesizedExpression>createSynthesizedNode(SyntaxKind.ParenthesizedExpression);
|
||||
@@ -1673,7 +1692,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
write("*");
|
||||
}
|
||||
|
||||
emit(node.name, /*allowGeneratedIdentifiers*/ false);
|
||||
emit(node.name);
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
write(": function ");
|
||||
}
|
||||
@@ -1681,40 +1700,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
function emitPropertyAssignment(node: PropertyDeclaration) {
|
||||
emit(node.name, /*allowGeneratedIdentifiers*/ false);
|
||||
emit(node.name);
|
||||
write(": ");
|
||||
emit(node.initializer);
|
||||
}
|
||||
|
||||
// Return true if identifier resolves to an exported member of a namespace
|
||||
function isNamespaceExportReference(node: Identifier) {
|
||||
let container = resolver.getReferencedExportContainer(node);
|
||||
return container && container.kind !== SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) {
|
||||
emit(node.name, /*allowGeneratedIdentifiers*/ false);
|
||||
// If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example:
|
||||
// module m {
|
||||
// export let y;
|
||||
// }
|
||||
// module m {
|
||||
// export let obj = { y };
|
||||
// }
|
||||
// The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
// The name property of a short-hand property assignment is considered an expression position, so here
|
||||
// we manually emit the identifier to avoid rewriting.
|
||||
writeTextOfNode(currentSourceFile, node.name);
|
||||
// If emitting pre-ES6 code, or if the name requires rewriting when resolved as an expression identifier,
|
||||
// we emit a normal property assignment. For example:
|
||||
// module m {
|
||||
// export let y;
|
||||
// }
|
||||
// module m {
|
||||
// let obj = { y };
|
||||
// }
|
||||
// Here we need to emit obj = { y : m.y } regardless of the output target.
|
||||
if (languageVersion < ScriptTarget.ES6 || isNamespaceExportReference(node.name)) {
|
||||
// Emit identifier as an identifier
|
||||
write(": ");
|
||||
var generatedName = getGeneratedNameForIdentifier(node.name);
|
||||
if (generatedName) {
|
||||
write(generatedName);
|
||||
}
|
||||
else {
|
||||
// Even though this is stored as identifier treat it as an expression
|
||||
// Short-hand, { x }, is equivalent of normal form { x: x }
|
||||
emitExpressionIdentifier(node.name);
|
||||
}
|
||||
}
|
||||
else if (resolver.getExpressionNameSubstitution(node.name, getGeneratedNameForNode)) {
|
||||
// Emit identifier as an identifier
|
||||
write(": ");
|
||||
// Even though this is stored as identifier treat it as an expression
|
||||
// Short-hand, { x }, is equivalent of normal form { x: x }
|
||||
emitExpressionIdentifier(node.name);
|
||||
emit(node.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1767,7 +1780,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
let indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
|
||||
write(".");
|
||||
let indentedAfterDot = indentIfOnDifferentLines(node, node.dotToken, node.name);
|
||||
emit(node.name, /*allowGeneratedIdentifiers*/ false);
|
||||
emit(node.name);
|
||||
decreaseIndentIf(indentedBeforeDot, indentedAfterDot);
|
||||
}
|
||||
|
||||
@@ -1889,23 +1902,21 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
function emitNewExpression(node: NewExpression) {
|
||||
write("new ");
|
||||
|
||||
// Spread operator logic can be supported in new expressions in ES5 using a combination
|
||||
// Spread operator logic is supported in new expressions in ES5 using a combination
|
||||
// of Function.prototype.bind() and Function.prototype.apply().
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var arguments = [1, 2, 3, 4, 5];
|
||||
// new Array(...arguments);
|
||||
// var args = [1, 2, 3, 4, 5];
|
||||
// new Array(...args);
|
||||
//
|
||||
// Could be transpiled into ES5:
|
||||
// is compiled into the following ES5:
|
||||
//
|
||||
// var arguments = [1, 2, 3, 4, 5];
|
||||
// new (Array.bind.apply(Array, [void 0].concat(arguments)));
|
||||
// var args = [1, 2, 3, 4, 5];
|
||||
// new (Array.bind.apply(Array, [void 0].concat(args)));
|
||||
//
|
||||
// `[void 0]` is the first argument which represents `thisArg` to the bind method above.
|
||||
// And `thisArg` will be set to the return value of the constructor when instantiated
|
||||
// with the new operator — regardless of any value we set `thisArg` to. Thus, we set it
|
||||
// to an undefined, `void 0`.
|
||||
// The 'thisArg' to 'bind' is ignored when invoking the result of 'bind' with 'new',
|
||||
// Thus, we set it to undefined ('void 0').
|
||||
if (languageVersion === ScriptTarget.ES5 &&
|
||||
node.arguments &&
|
||||
hasSpreadElement(node.arguments)) {
|
||||
@@ -1941,13 +1952,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
function emitParenExpression(node: ParenthesizedExpression) {
|
||||
if (!node.parent || node.parent.kind !== SyntaxKind.ArrowFunction) {
|
||||
// If the node is synthesized, it means the emitter put the parentheses there,
|
||||
// not the user. If we didn't want them, the emitter would not have put them
|
||||
// there.
|
||||
if (!nodeIsSynthesized(node) && node.parent.kind !== SyntaxKind.ArrowFunction) {
|
||||
if (node.expression.kind === SyntaxKind.TypeAssertionExpression) {
|
||||
let operand = (<TypeAssertion>node.expression).expression;
|
||||
|
||||
// Make sure we consider all nested cast expressions, e.g.:
|
||||
// (<any><number><any>-A).x;
|
||||
while (operand.kind == SyntaxKind.TypeAssertionExpression) {
|
||||
while (operand.kind === SyntaxKind.TypeAssertionExpression) {
|
||||
operand = (<TypeAssertion>operand).expression;
|
||||
}
|
||||
|
||||
@@ -2769,8 +2783,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
write(", ");
|
||||
}
|
||||
|
||||
renameNonTopLevelLetAndConst(name);
|
||||
|
||||
const isVariableDeclarationOrBindingElement =
|
||||
name.parent && (name.parent.kind === SyntaxKind.VariableDeclaration || name.parent.kind === SyntaxKind.BindingElement);
|
||||
|
||||
@@ -2838,11 +2850,14 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
|
||||
function createPropertyAccessForDestructuringProperty(object: Expression, propName: Identifier | LiteralExpression): Expression {
|
||||
if (propName.kind !== SyntaxKind.Identifier) {
|
||||
return createElementAccessExpression(object, propName);
|
||||
// We create a synthetic copy of the identifier in order to avoid the rewriting that might
|
||||
// otherwise occur when the identifier is emitted.
|
||||
let syntheticName = <Identifier | LiteralExpression>createSynthesizedNode(propName.kind);
|
||||
syntheticName.text = propName.text;
|
||||
if (syntheticName.kind !== SyntaxKind.Identifier) {
|
||||
return createElementAccessExpression(object, syntheticName);
|
||||
}
|
||||
|
||||
return createPropertyAccessExpression(object, propName);
|
||||
return createPropertyAccessExpression(object, syntheticName);
|
||||
}
|
||||
|
||||
function createSliceCall(value: Expression, sliceIndex: number): CallExpression {
|
||||
@@ -2864,8 +2879,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
for (let p of properties) {
|
||||
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
// TODO(andersh): Computed property support
|
||||
let propName = <Identifier | LiteralExpression>((<PropertyAssignment>p).name);
|
||||
let propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
|
||||
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, createPropertyAccessForDestructuringProperty(value, propName));
|
||||
}
|
||||
}
|
||||
@@ -2979,8 +2993,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
renameNonTopLevelLetAndConst(<Identifier>node.name);
|
||||
|
||||
let initializer = node.initializer;
|
||||
if (!initializer && languageVersion < ScriptTarget.ES6) {
|
||||
|
||||
@@ -3040,54 +3052,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return getCombinedNodeFlags(node.parent);
|
||||
}
|
||||
|
||||
function renameNonTopLevelLetAndConst(node: Node): void {
|
||||
// do not rename if
|
||||
// - language version is ES6+
|
||||
// - node is synthesized
|
||||
// - node is not identifier (can happen when tree is malformed)
|
||||
// - node is definitely not name of variable declaration.
|
||||
// it still can be part of parameter declaration, this check will be done next
|
||||
if (languageVersion >= ScriptTarget.ES6 ||
|
||||
nodeIsSynthesized(node) ||
|
||||
node.kind !== SyntaxKind.Identifier ||
|
||||
(node.parent.kind !== SyntaxKind.VariableDeclaration && node.parent.kind !== SyntaxKind.BindingElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let combinedFlags = getCombinedFlagsForIdentifier(<Identifier>node);
|
||||
if (((combinedFlags & NodeFlags.BlockScoped) === 0) || combinedFlags & NodeFlags.Export) {
|
||||
// do not rename exported or non-block scoped variables
|
||||
return;
|
||||
}
|
||||
|
||||
// here it is known that node is a block scoped variable
|
||||
let list = getAncestor(node, SyntaxKind.VariableDeclarationList);
|
||||
if (list.parent.kind === SyntaxKind.VariableStatement) {
|
||||
let isSourceFileLevelBinding = list.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
let isModuleLevelBinding = list.parent.parent.kind === SyntaxKind.ModuleBlock;
|
||||
let isFunctionLevelBinding =
|
||||
list.parent.parent.kind === SyntaxKind.Block && isFunctionLike(list.parent.parent.parent);
|
||||
if (isSourceFileLevelBinding || isModuleLevelBinding || isFunctionLevelBinding) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let blockScopeContainer = getEnclosingBlockScopeContainer(node);
|
||||
let parent = blockScopeContainer.kind === SyntaxKind.SourceFile
|
||||
? blockScopeContainer
|
||||
: blockScopeContainer.parent;
|
||||
|
||||
if (resolver.resolvesToSomeValue(parent, (<Identifier>node).text)) {
|
||||
let variableId = resolver.getBlockScopedVariableId(<Identifier>node);
|
||||
if (!blockScopedVariableToGeneratedName) {
|
||||
blockScopedVariableToGeneratedName = [];
|
||||
}
|
||||
|
||||
let generatedName = makeUniqueName((<Identifier>node).text);
|
||||
blockScopedVariableToGeneratedName[variableId] = generatedName;
|
||||
}
|
||||
}
|
||||
|
||||
function isES6ExportedDeclaration(node: Node) {
|
||||
return !!(node.flags & NodeFlags.Export) &&
|
||||
languageVersion >= ScriptTarget.ES6 &&
|
||||
@@ -3251,7 +3215,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
function emitAccessor(node: AccessorDeclaration) {
|
||||
write(node.kind === SyntaxKind.GetAccessor ? "get " : "set ");
|
||||
emit(node.name, /*allowGeneratedIdentifiers*/ false);
|
||||
emit(node.name);
|
||||
emitSignatureAndBody(node);
|
||||
}
|
||||
|
||||
@@ -4354,7 +4318,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
let argumentsWritten = 0;
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
if (shouldEmitTypeMetadata(node)) {
|
||||
var serializedType = resolver.serializeTypeOfNode(node, getGeneratedNameForNode);
|
||||
var serializedType = resolver.serializeTypeOfNode(node);
|
||||
if (serializedType) {
|
||||
if (writeComma) {
|
||||
write(", ");
|
||||
@@ -4367,7 +4331,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
if (shouldEmitParamTypesMetadata(node)) {
|
||||
var serializedTypes = resolver.serializeParameterTypesOfNode(node, getGeneratedNameForNode);
|
||||
var serializedTypes = resolver.serializeParameterTypesOfNode(node);
|
||||
if (serializedTypes) {
|
||||
if (writeComma || argumentsWritten) {
|
||||
write(", ");
|
||||
@@ -4385,7 +4349,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
if (shouldEmitReturnTypeMetadata(node)) {
|
||||
var serializedType = resolver.serializeReturnTypeOfNode(node, getGeneratedNameForNode);
|
||||
var serializedType = resolver.serializeReturnTypeOfNode(node);
|
||||
if (serializedType) {
|
||||
if (writeComma || argumentsWritten) {
|
||||
write(", ");
|
||||
@@ -4491,7 +4455,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
emitDeclarationName(node);
|
||||
write(`", `);
|
||||
emitDeclarationName(node);
|
||||
write(")");
|
||||
write(");");
|
||||
}
|
||||
emitExportMemberAssignments(node.name);
|
||||
}
|
||||
@@ -4612,7 +4576,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
emitDeclarationName(node);
|
||||
write(`", `);
|
||||
emitDeclarationName(node);
|
||||
write(")");
|
||||
write(");");
|
||||
}
|
||||
emitExportMemberAssignments(<Identifier>node.name);
|
||||
}
|
||||
@@ -4983,13 +4947,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
}
|
||||
}
|
||||
|
||||
function getLocalNameForExternalImport(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string {
|
||||
let namespaceDeclaration = getNamespaceDeclarationNode(importNode);
|
||||
if (namespaceDeclaration && !isDefaultImport(importNode)) {
|
||||
function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string {
|
||||
let namespaceDeclaration = getNamespaceDeclarationNode(node);
|
||||
if (namespaceDeclaration && !isDefaultImport(node)) {
|
||||
return getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
|
||||
}
|
||||
else {
|
||||
return getGeneratedNameForNode(<ImportDeclaration | ExportDeclaration>importNode);
|
||||
if (node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).importClause) {
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
if (node.kind === SyntaxKind.ExportDeclaration && (<ExportDeclaration>node).moduleSpecifier) {
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5377,10 +5344,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
emitSetters(exportStarFunction);
|
||||
writeLine();
|
||||
emitExecute(node, startIndex);
|
||||
emitTempDeclarations(/*newLine*/ true)
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
write("}"); // return
|
||||
emitTempDeclarations(/*newLine*/ true);
|
||||
}
|
||||
|
||||
function emitSetters(exportStarFunction: string) {
|
||||
@@ -5527,7 +5494,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
Debug.assert(!exportFunctionForFile);
|
||||
// make sure that name of 'exports' function does not conflict with existing identifiers
|
||||
exportFunctionForFile = makeUniqueName("exports");
|
||||
write("System.register([");
|
||||
write("System.register(");
|
||||
if (node.moduleName) {
|
||||
write(`"${node.moduleName}", `);
|
||||
}
|
||||
write("[")
|
||||
for (let i = 0; i < externalImports.length; ++i) {
|
||||
let text = getExternalModuleNameText(externalImports[i]);
|
||||
if (i !== 0) {
|
||||
@@ -5613,8 +5584,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
|
||||
writeLine();
|
||||
write("define(");
|
||||
if (node.amdModuleName) {
|
||||
write("\"" + node.amdModuleName + "\", ");
|
||||
if (node.moduleName) {
|
||||
write("\"" + node.moduleName + "\", ");
|
||||
}
|
||||
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true);
|
||||
write(") {");
|
||||
@@ -5774,7 +5745,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
emitLeadingComments(node.endOfFileToken);
|
||||
}
|
||||
|
||||
function emitNodeWithoutSourceMap(node: Node, allowGeneratedIdentifiers?: boolean): void {
|
||||
function emitNodeWithoutSourceMap(node: Node): void {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
@@ -5788,7 +5759,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
emitLeadingComments(node);
|
||||
}
|
||||
|
||||
emitJavaScriptWorker(node, allowGeneratedIdentifiers);
|
||||
emitJavaScriptWorker(node);
|
||||
|
||||
if (emitComments) {
|
||||
emitTrailingComments(node);
|
||||
@@ -5838,11 +5809,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function emitJavaScriptWorker(node: Node, allowGeneratedIdentifiers: boolean = true) {
|
||||
function emitJavaScriptWorker(node: Node) {
|
||||
// Check if the node can be emitted regardless of the ScriptTarget
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return emitIdentifier(<Identifier>node, allowGeneratedIdentifiers);
|
||||
return emitIdentifier(<Identifier>node);
|
||||
case SyntaxKind.Parameter:
|
||||
return emitParameter(<ParameterDeclaration>node);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
|
||||
+140
-175
@@ -1,7 +1,7 @@
|
||||
/// <reference path="scanner.ts"/>
|
||||
/// <reference path="utilities.ts"/>
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
let nodeConstructors = new Array<new () => Node>(SyntaxKind.Count);
|
||||
/* @internal */ export let parseTime = 0;
|
||||
|
||||
@@ -103,6 +103,9 @@ module ts {
|
||||
case SyntaxKind.TypeReference:
|
||||
return visitNode(cbNode, (<TypeReferenceNode>node).typeName) ||
|
||||
visitNodes(cbNodes, (<TypeReferenceNode>node).typeArguments);
|
||||
case SyntaxKind.TypePredicate:
|
||||
return visitNode(cbNode, (<TypePredicateNode>node).parameterName) ||
|
||||
visitNode(cbNode, (<TypePredicateNode>node).type);
|
||||
case SyntaxKind.TypeQuery:
|
||||
return visitNode(cbNode, (<TypeQueryNode>node).exprName);
|
||||
case SyntaxKind.TypeLiteral:
|
||||
@@ -255,6 +258,7 @@ module ts {
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<TypeAliasDeclaration>node).name) ||
|
||||
visitNodes(cbNodes, (<TypeAliasDeclaration>node).typeParameters) ||
|
||||
visitNode(cbNode, (<TypeAliasDeclaration>node).type);
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
@@ -491,13 +495,6 @@ module ts {
|
||||
// attached to the EOF token.
|
||||
let parseErrorBeforeNextFinishedNode: boolean = false;
|
||||
|
||||
export const enum StatementFlags {
|
||||
None = 0,
|
||||
Statement = 1,
|
||||
ModuleElement = 2,
|
||||
StatementOrModuleElement = Statement | ModuleElement
|
||||
}
|
||||
|
||||
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile {
|
||||
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
|
||||
|
||||
@@ -547,7 +544,7 @@ module ts {
|
||||
token = nextToken();
|
||||
processReferenceComments(sourceFile);
|
||||
|
||||
sourceFile.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement);
|
||||
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
|
||||
Debug.assert(token === SyntaxKind.EndOfFileToken);
|
||||
sourceFile.endOfFileToken = parseTokenNode();
|
||||
|
||||
@@ -650,10 +647,6 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function setStrictModeContext(val: boolean) {
|
||||
setContextFlag(val, ParserContextFlags.StrictMode);
|
||||
}
|
||||
|
||||
function setDisallowInContext(val: boolean) {
|
||||
setContextFlag(val, ParserContextFlags.DisallowIn);
|
||||
}
|
||||
@@ -747,10 +740,6 @@ module ts {
|
||||
return (contextFlags & ParserContextFlags.Yield) !== 0;
|
||||
}
|
||||
|
||||
function inStrictModeContext() {
|
||||
return (contextFlags & ParserContextFlags.StrictMode) !== 0;
|
||||
}
|
||||
|
||||
function inGeneratorParameterContext() {
|
||||
return (contextFlags & ParserContextFlags.GeneratorParameter) !== 0;
|
||||
}
|
||||
@@ -1125,17 +1114,14 @@ module ts {
|
||||
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.SourceElements:
|
||||
case ParsingContext.ModuleElements:
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
// If we're in error recovery, then we don't want to treat ';' as an empty statement.
|
||||
// The problem is that ';' can show up in far too many contexts, and if we see one
|
||||
// and assume it's a statement, then we may bail out inappropriately from whatever
|
||||
// we're parsing. For example, if we have a semicolon in the middle of a class, then
|
||||
// we really don't want to assume the class is over and we're on a statement in the
|
||||
// outer module. We just want to consume and move on.
|
||||
return !(token === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfModuleElement();
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
// During error recovery we don't treat empty statements as statements
|
||||
return !(token === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement();
|
||||
case ParsingContext.SwitchClauses:
|
||||
return token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
|
||||
@@ -1246,7 +1232,6 @@ module ts {
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case ParsingContext.ModuleElements:
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauses:
|
||||
case ParsingContext.TypeMembers:
|
||||
@@ -1330,31 +1315,17 @@ module ts {
|
||||
}
|
||||
|
||||
// Parses a list of elements
|
||||
function parseList<T extends Node>(kind: ParsingContext, checkForStrictMode: boolean, parseElement: () => T): NodeArray<T> {
|
||||
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
|
||||
let saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << kind;
|
||||
let result = <NodeArray<T>>[];
|
||||
result.pos = getNodePos();
|
||||
let savedStrictModeContext = inStrictModeContext();
|
||||
|
||||
while (!isListTerminator(kind)) {
|
||||
if (isListElement(kind, /* inErrorRecovery */ false)) {
|
||||
let element = parseListElement(kind, parseElement);
|
||||
result.push(element);
|
||||
|
||||
// test elements only if we are not already in strict mode
|
||||
if (checkForStrictMode && !inStrictModeContext()) {
|
||||
if (isPrologueDirective(element)) {
|
||||
if (isUseStrictPrologueDirective(element)) {
|
||||
setStrictModeContext(true);
|
||||
checkForStrictMode = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
checkForStrictMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1363,22 +1334,11 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
setStrictModeContext(savedStrictModeContext);
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Should be called only on prologue directives (isPrologueDirective(node) should be true)
|
||||
function isUseStrictPrologueDirective(node: Node): boolean {
|
||||
Debug.assert(isPrologueDirective(node));
|
||||
let nodeText = getTextOfNodeFromSourceText(sourceText, (<ExpressionStatement>node).expression);
|
||||
|
||||
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
|
||||
// string to contain unicode escapes (as per ES5).
|
||||
return nodeText === '"use strict"' || nodeText === "'use strict'";
|
||||
}
|
||||
|
||||
function parseListElement<T extends Node>(parsingContext: ParsingContext, parseElement: () => T): T {
|
||||
let node = currentNode(parsingContext);
|
||||
if (node) {
|
||||
@@ -1457,15 +1417,13 @@ module ts {
|
||||
|
||||
function canReuseNode(node: Node, parsingContext: ParsingContext): boolean {
|
||||
switch (parsingContext) {
|
||||
case ParsingContext.ModuleElements:
|
||||
return isReusableModuleElement(node);
|
||||
|
||||
case ParsingContext.ClassMembers:
|
||||
return isReusableClassMember(node);
|
||||
|
||||
case ParsingContext.SwitchClauses:
|
||||
return isReusableSwitchClause(node);
|
||||
|
||||
case ParsingContext.SourceElements:
|
||||
case ParsingContext.BlockStatements:
|
||||
case ParsingContext.SwitchClauseStatements:
|
||||
return isReusableStatement(node);
|
||||
@@ -1528,37 +1486,25 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isReusableModuleElement(node: Node) {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return true;
|
||||
}
|
||||
|
||||
return isReusableStatement(node);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isReusableClassMember(node: Node) {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
return true;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// Method declarations are not necessarily reusable. An object-literal
|
||||
// may have a method calls "constructor(...)" and we must reparse that
|
||||
// into an actual .ConstructorDeclaration.
|
||||
let methodDeclaration = <MethodDeclaration>node;
|
||||
let nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>methodDeclaration.name).originalKeywordKind === SyntaxKind.ConstructorKeyword;
|
||||
|
||||
return !nameIsConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1600,6 +1546,15 @@ module ts {
|
||||
case SyntaxKind.LabeledStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.DebuggerStatement:
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1673,8 +1628,7 @@ module ts {
|
||||
function parsingContextErrors(context: ParsingContext): DiagnosticMessage {
|
||||
switch (context) {
|
||||
case ParsingContext.SourceElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.ModuleElements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.BlockStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.BlockStatements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected;
|
||||
case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
|
||||
@@ -1791,32 +1745,32 @@ module ts {
|
||||
}
|
||||
|
||||
function parseRightSideOfDot(allowIdentifierNames: boolean): Identifier {
|
||||
// Technically a keyword is valid here as all keywords are identifier names.
|
||||
// However, often we'll encounter this in error situations when the keyword
|
||||
// Technically a keyword is valid here as all identifiers and keywords are identifier names.
|
||||
// However, often we'll encounter this in error situations when the identifier or keyword
|
||||
// is actually starting another valid construct.
|
||||
//
|
||||
// So, we check for the following specific case:
|
||||
//
|
||||
// name.
|
||||
// keyword identifierNameOrKeyword
|
||||
// identifierOrKeyword identifierNameOrKeyword
|
||||
//
|
||||
// Note: the newlines are important here. For example, if that above code
|
||||
// were rewritten into:
|
||||
//
|
||||
// name.keyword
|
||||
// name.identifierOrKeyword
|
||||
// identifierNameOrKeyword
|
||||
//
|
||||
// Then we would consider it valid. That's because ASI would take effect and
|
||||
// the code would be implicitly: "name.keyword; identifierNameOrKeyword".
|
||||
// the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
|
||||
// In the first case though, ASI will not take effect because there is not a
|
||||
// line terminator after the keyword.
|
||||
if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord()) {
|
||||
// line terminator after the identifier or keyword.
|
||||
if (scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword()) {
|
||||
let matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
|
||||
|
||||
if (matchesPattern) {
|
||||
// Report that we need an identifier. However, report it right after the dot,
|
||||
// and not on the next token. This is because the next token might actually
|
||||
// be an identifier and the error woudl be quite confusing.
|
||||
// be an identifier and the error would be quite confusing.
|
||||
return <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken*/ true, Diagnostics.Identifier_expected);
|
||||
}
|
||||
}
|
||||
@@ -1897,9 +1851,17 @@ module ts {
|
||||
|
||||
// TYPES
|
||||
|
||||
function parseTypeReference(): TypeReferenceNode {
|
||||
let node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
||||
node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
||||
function parseTypeReferenceOrTypePredicate(): TypeReferenceNode | TypePredicateNode {
|
||||
let typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
||||
if (typeName.kind === SyntaxKind.Identifier && token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) {
|
||||
nextToken();
|
||||
let node = <TypePredicateNode>createNode(SyntaxKind.TypePredicate, typeName.pos);
|
||||
node.parameterName = <Identifier>typeName;
|
||||
node.type = parseType();
|
||||
return finishNode(node);
|
||||
}
|
||||
let node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference, typeName.pos);
|
||||
node.typeName = typeName;
|
||||
if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) {
|
||||
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
@@ -2289,7 +2251,7 @@ module ts {
|
||||
function parseObjectTypeMembers(): NodeArray<Declaration> {
|
||||
let members: NodeArray<Declaration>;
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken)) {
|
||||
members = parseList(ParsingContext.TypeMembers, /*checkForStrictMode*/ false, parseTypeMember);
|
||||
members = parseList(ParsingContext.TypeMembers, parseTypeMember);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
@@ -2336,7 +2298,7 @@ module ts {
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
// If these are followed by a dot, then parse these out as a dotted type reference instead.
|
||||
let node = tryParse(parseKeywordAndNoDot);
|
||||
return node || parseTypeReference();
|
||||
return node || parseTypeReferenceOrTypePredicate();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
case SyntaxKind.TypeOfKeyword:
|
||||
@@ -2348,7 +2310,7 @@ module ts {
|
||||
case SyntaxKind.OpenParenToken:
|
||||
return parseParenthesizedType();
|
||||
default:
|
||||
return parseTypeReference();
|
||||
return parseTypeReferenceOrTypePredicate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2658,12 +2620,6 @@ module ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inStrictModeContext()) {
|
||||
// If we're in strict mode, then 'yield' is a keyword, could only ever start
|
||||
// a yield expression.
|
||||
return true;
|
||||
}
|
||||
|
||||
// We're in a context where 'yield expr' is not allowed. However, if we can
|
||||
// definitely tell that the user was trying to parse a 'yield expr' and not
|
||||
// just a normal expr that start with a 'yield' identifier, then parse out
|
||||
@@ -2678,7 +2634,7 @@ module ts {
|
||||
// for now we just check if the next token is an identifier. More heuristics
|
||||
// can be added here later as necessary. We just need to make sure that we
|
||||
// don't accidently consume something legal.
|
||||
return lookAhead(nextTokenIsIdentifierOnSameLine);
|
||||
return lookAhead(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2686,7 +2642,7 @@ module ts {
|
||||
|
||||
function nextTokenIsIdentifierOnSameLine() {
|
||||
nextToken();
|
||||
return !scanner.hasPrecedingLineBreak() && isIdentifier()
|
||||
return !scanner.hasPrecedingLineBreak() && isIdentifier();
|
||||
}
|
||||
|
||||
function parseYieldExpression(): YieldExpression {
|
||||
@@ -3521,10 +3477,10 @@ module ts {
|
||||
}
|
||||
|
||||
// STATEMENTS
|
||||
function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean, diagnosticMessage?: DiagnosticMessage): Block {
|
||||
function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block {
|
||||
let node = <Block>createNode(SyntaxKind.Block);
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) {
|
||||
node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatement);
|
||||
node.statements = parseList(ParsingContext.BlockStatements, parseStatement);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
@@ -3544,7 +3500,7 @@ module ts {
|
||||
setDecoratorContext(false);
|
||||
}
|
||||
|
||||
let block = parseBlock(ignoreMissingOpenBrace, /*checkForStrictMode*/ true, diagnosticMessage);
|
||||
let block = parseBlock(ignoreMissingOpenBrace, diagnosticMessage);
|
||||
|
||||
if (saveDecoratorContext) {
|
||||
setDecoratorContext(true);
|
||||
@@ -3686,7 +3642,7 @@ module ts {
|
||||
parseExpected(SyntaxKind.CaseKeyword);
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -3694,7 +3650,7 @@ module ts {
|
||||
let node = <DefaultClause>createNode(SyntaxKind.DefaultClause);
|
||||
parseExpected(SyntaxKind.DefaultKeyword);
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement);
|
||||
node.statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -3710,7 +3666,7 @@ module ts {
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
let caseBlock = <CaseBlock>createNode(SyntaxKind.CaseBlock, scanner.getStartPos());
|
||||
parseExpected(SyntaxKind.OpenBraceToken);
|
||||
caseBlock.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause);
|
||||
caseBlock.clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
node.caseBlock = finishNode(caseBlock);
|
||||
return finishNode(node);
|
||||
@@ -3737,14 +3693,14 @@ module ts {
|
||||
let node = <TryStatement>createNode(SyntaxKind.TryStatement);
|
||||
|
||||
parseExpected(SyntaxKind.TryKeyword);
|
||||
node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false);
|
||||
node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
|
||||
node.catchClause = token === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined;
|
||||
|
||||
// If we don't have a catch clause, then we must have a finally clause. Try to parse
|
||||
// one out no matter what.
|
||||
if (!node.catchClause || token === SyntaxKind.FinallyKeyword) {
|
||||
parseExpected(SyntaxKind.FinallyKeyword);
|
||||
node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false);
|
||||
node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
|
||||
}
|
||||
|
||||
return finishNode(node);
|
||||
@@ -3758,7 +3714,7 @@ module ts {
|
||||
}
|
||||
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
result.block = parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false);
|
||||
result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
@@ -3799,7 +3755,12 @@ module ts {
|
||||
return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function parseDeclarationFlags(): StatementFlags {
|
||||
function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
|
||||
nextToken();
|
||||
return (isIdentifierOrKeyword() || token === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function isDeclaration(): boolean {
|
||||
while (true) {
|
||||
switch (token) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
@@ -3808,28 +3769,54 @@ module ts {
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
return StatementFlags.Statement;
|
||||
return true;
|
||||
|
||||
// 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
|
||||
// however, an identifier cannot be followed by another identifier on the same line. This is what we
|
||||
// count on to parse out the respective declarations. For instance, we exploit this to say that
|
||||
//
|
||||
// namespace n
|
||||
//
|
||||
// can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
|
||||
//
|
||||
// namespace
|
||||
// n
|
||||
//
|
||||
// as the identifier 'namespace' on one line followed by the identifier 'n' on another.
|
||||
// We need to look one token ahead to see if it permissible to try parsing a declaration.
|
||||
//
|
||||
// *Note*: 'interface' is actually a strict mode reserved word. So while
|
||||
//
|
||||
// "use strict"
|
||||
// interface
|
||||
// I {}
|
||||
//
|
||||
// could be legal, it would add complexity for very little gain.
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
nextToken();
|
||||
return isIdentifierOrKeyword() ? StatementFlags.Statement : StatementFlags.None;
|
||||
return nextTokenIsIdentifierOnSameLine();
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
return nextTokenIsIdentifierOrStringLiteralOnSameLine();
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
nextToken();
|
||||
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral ? StatementFlags.ModuleElement : StatementFlags.None;
|
||||
// ASI takes effect for this modifier.
|
||||
if (scanner.hasPrecedingLineBreak()) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
|
||||
case SyntaxKind.ImportKeyword:
|
||||
nextToken();
|
||||
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
|
||||
token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword() ?
|
||||
StatementFlags.ModuleElement : StatementFlags.None;
|
||||
token === SyntaxKind.OpenBraceToken || isIdentifierOrKeyword();
|
||||
case SyntaxKind.ExportKeyword:
|
||||
nextToken();
|
||||
if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken ||
|
||||
token === SyntaxKind.OpenBraceToken || token === SyntaxKind.DefaultKeyword) {
|
||||
return StatementFlags.ModuleElement;
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
@@ -3837,16 +3824,16 @@ module ts {
|
||||
nextToken();
|
||||
continue;
|
||||
default:
|
||||
return StatementFlags.None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationFlags(): StatementFlags {
|
||||
return lookAhead(parseDeclarationFlags);
|
||||
function isStartOfDeclaration(): boolean {
|
||||
return lookAhead(isDeclaration);
|
||||
}
|
||||
|
||||
function getStatementFlags(): StatementFlags {
|
||||
function isStartOfStatement(): boolean {
|
||||
switch (token) {
|
||||
case SyntaxKind.AtToken:
|
||||
case SyntaxKind.SemicolonToken:
|
||||
@@ -3872,12 +3859,12 @@ module ts {
|
||||
// however, we say they are here so that we may gracefully parse them and error later.
|
||||
case SyntaxKind.CatchKeyword:
|
||||
case SyntaxKind.FinallyKeyword:
|
||||
return StatementFlags.Statement;
|
||||
return true;
|
||||
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
return getDeclarationFlags();
|
||||
return isStartOfDeclaration();
|
||||
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
@@ -3885,7 +3872,7 @@ module ts {
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
// When these don't start a declaration, they're an identifier in an expression statement
|
||||
return getDeclarationFlags() || StatementFlags.Statement;
|
||||
return true;
|
||||
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
@@ -3893,52 +3880,30 @@ module ts {
|
||||
case SyntaxKind.StaticKeyword:
|
||||
// When these don't start a declaration, they may be the start of a class member if an identifier
|
||||
// immediately follows. Otherwise they're an identifier in an expression statement.
|
||||
return getDeclarationFlags() ||
|
||||
(lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? StatementFlags.None : StatementFlags.Statement);
|
||||
return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
|
||||
|
||||
default:
|
||||
return isStartOfExpression() ? StatementFlags.Statement : StatementFlags.None;
|
||||
return isStartOfExpression();
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfStatement(): boolean {
|
||||
return (getStatementFlags() & StatementFlags.Statement) !== 0;
|
||||
}
|
||||
|
||||
function isStartOfModuleElement(): boolean {
|
||||
return (getStatementFlags() & StatementFlags.StatementOrModuleElement) !== 0;
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() {
|
||||
function nextTokenIsIdentifierOrStartOfDestructuring() {
|
||||
nextToken();
|
||||
return !scanner.hasPrecedingLineBreak() &&
|
||||
(isIdentifier() || token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken);
|
||||
return isIdentifier() || token === SyntaxKind.OpenBraceToken || token === SyntaxKind.OpenBracketToken;
|
||||
}
|
||||
|
||||
function isLetDeclaration() {
|
||||
// It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line.
|
||||
// otherwise it needs to be treated like identifier
|
||||
return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine);
|
||||
// In ES6 'let' always starts a lexical declaration if followed by an identifier or {
|
||||
// or [.
|
||||
return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
|
||||
}
|
||||
|
||||
function parseStatement(): Statement {
|
||||
return <Statement>parseModuleElementOfKind(StatementFlags.Statement);
|
||||
}
|
||||
|
||||
function parseModuleElement(): ModuleElement {
|
||||
return parseModuleElementOfKind(StatementFlags.StatementOrModuleElement);
|
||||
}
|
||||
|
||||
function parseSourceElement(): ModuleElement {
|
||||
return parseModuleElementOfKind(StatementFlags.StatementOrModuleElement);
|
||||
}
|
||||
|
||||
function parseModuleElementOfKind(flags: StatementFlags): ModuleElement {
|
||||
switch (token) {
|
||||
case SyntaxKind.SemicolonToken:
|
||||
return parseEmptyStatement();
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return parseBlock(/*ignoreMissingOpenBrace*/ false, /*checkForStrictMode*/ false);
|
||||
return parseBlock(/*ignoreMissingOpenBrace*/ false);
|
||||
case SyntaxKind.VarKeyword:
|
||||
return parseVariableStatement(scanner.getStartPos(), /*decorators*/ undefined, /*modifiers*/ undefined);
|
||||
case SyntaxKind.LetKeyword:
|
||||
@@ -3971,7 +3936,7 @@ module ts {
|
||||
case SyntaxKind.ThrowKeyword:
|
||||
return parseThrowStatement();
|
||||
case SyntaxKind.TryKeyword:
|
||||
// Include the next two for error recovery.
|
||||
// Include 'catch' and 'finally' for error recovery.
|
||||
case SyntaxKind.CatchKeyword:
|
||||
case SyntaxKind.FinallyKeyword:
|
||||
return parseTryStatement();
|
||||
@@ -3979,20 +3944,21 @@ module ts {
|
||||
return parseDebuggerStatement();
|
||||
case SyntaxKind.AtToken:
|
||||
return parseDeclaration();
|
||||
case SyntaxKind.ConstKeyword:
|
||||
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.EnumKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.InterfaceKeyword:
|
||||
case SyntaxKind.ModuleKeyword:
|
||||
case SyntaxKind.NamespaceKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.TypeKeyword:
|
||||
if (getDeclarationFlags() & flags) {
|
||||
if (isStartOfDeclaration()) {
|
||||
return parseDeclaration();
|
||||
}
|
||||
break;
|
||||
@@ -4000,7 +3966,7 @@ module ts {
|
||||
return parseExpressionOrLabeledStatement();
|
||||
}
|
||||
|
||||
function parseDeclaration(): ModuleElement {
|
||||
function parseDeclaration(): Statement {
|
||||
let fullStart = getNodePos();
|
||||
let decorators = parseDecorators();
|
||||
let modifiers = parseModifiers();
|
||||
@@ -4030,10 +3996,10 @@ module ts {
|
||||
parseExportAssignment(fullStart, decorators, modifiers) :
|
||||
parseExportDeclaration(fullStart, decorators, modifiers);
|
||||
default:
|
||||
if (decorators) {
|
||||
if (decorators || modifiers) {
|
||||
// We reached this point because we encountered decorators and/or modifiers and assumed a declaration
|
||||
// would follow. For recovery and error reporting purposes, return an incomplete declaration.
|
||||
let node = <ModuleElement>createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
|
||||
let node = <Statement>createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
|
||||
node.pos = fullStart;
|
||||
node.decorators = decorators;
|
||||
setModifiers(node, modifiers);
|
||||
@@ -4042,6 +4008,11 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
|
||||
nextToken();
|
||||
return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral);
|
||||
}
|
||||
|
||||
function parseFunctionBlockOrSemicolon(isGenerator: boolean, diagnosticMessage?: DiagnosticMessage): Block {
|
||||
if (token !== SyntaxKind.OpenBraceToken && canParseSemicolon()) {
|
||||
parseSemicolon();
|
||||
@@ -4427,7 +4398,7 @@ module ts {
|
||||
return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers);
|
||||
}
|
||||
|
||||
if (decorators) {
|
||||
if (decorators || modifiers) {
|
||||
// treat this as a property declaration with a missing name.
|
||||
let name = <Identifier>createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
|
||||
return parsePropertyDeclaration(fullStart, decorators, modifiers, name, /*questionToken*/ undefined);
|
||||
@@ -4450,10 +4421,6 @@ module ts {
|
||||
}
|
||||
|
||||
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();
|
||||
setStrictModeContext(true);
|
||||
|
||||
var node = <ClassLikeDeclaration>createNode(kind, fullStart);
|
||||
node.decorators = decorators;
|
||||
setModifiers(node, modifiers);
|
||||
@@ -4476,9 +4443,7 @@ module ts {
|
||||
node.members = createMissingList<ClassElement>();
|
||||
}
|
||||
|
||||
var finishedNode = finishNode(node);
|
||||
setStrictModeContext(savedStrictModeContext);
|
||||
return finishedNode;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
|
||||
@@ -4496,7 +4461,7 @@ module ts {
|
||||
}
|
||||
|
||||
function parseHeritageClausesWorker() {
|
||||
return parseList(ParsingContext.HeritageClauses, /*checkForStrictMode*/ false, parseHeritageClause);
|
||||
return parseList(ParsingContext.HeritageClauses, parseHeritageClause);
|
||||
}
|
||||
|
||||
function parseHeritageClause() {
|
||||
@@ -4526,7 +4491,7 @@ module ts {
|
||||
}
|
||||
|
||||
function parseClassMembers() {
|
||||
return parseList(ParsingContext.ClassMembers, /*checkForStrictMode*/ false, parseClassElement);
|
||||
return parseList(ParsingContext.ClassMembers, parseClassElement);
|
||||
}
|
||||
|
||||
function parseInterfaceDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): InterfaceDeclaration {
|
||||
@@ -4547,6 +4512,7 @@ module ts {
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.TypeKeyword);
|
||||
node.name = parseIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
node.type = parseType();
|
||||
parseSemicolon();
|
||||
@@ -4583,7 +4549,7 @@ module ts {
|
||||
function parseModuleBlock(): ModuleBlock {
|
||||
let node = <ModuleBlock>createNode(SyntaxKind.ModuleBlock, scanner.getStartPos());
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken)) {
|
||||
node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/false, parseModuleElement);
|
||||
node.statements = parseList(ParsingContext.BlockStatements, parseStatement);
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
else {
|
||||
@@ -4895,7 +4861,7 @@ module ts {
|
||||
|
||||
sourceFile.referencedFiles = referencedFiles;
|
||||
sourceFile.amdDependencies = amdDependencies;
|
||||
sourceFile.amdModuleName = amdModuleName;
|
||||
sourceFile.moduleName = amdModuleName;
|
||||
}
|
||||
|
||||
function setExternalModuleIndicator(sourceFile: SourceFile) {
|
||||
@@ -4911,7 +4877,6 @@ module ts {
|
||||
|
||||
const enum ParsingContext {
|
||||
SourceElements, // Elements in source file
|
||||
ModuleElements, // Elements in module declaration
|
||||
BlockStatements, // Statements in block
|
||||
SwitchClauses, // Clauses in switch statement
|
||||
SwitchClauseStatements, // Statements in switch clause
|
||||
|
||||
+65
-35
@@ -1,7 +1,7 @@
|
||||
/// <reference path="sys.ts" />
|
||||
/// <reference path="emitter.ts" />
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
/* @internal */ export let programTime = 0;
|
||||
/* @internal */ export let emitTime = 0;
|
||||
/* @internal */ export let ioReadTime = 0;
|
||||
@@ -10,9 +10,6 @@ module ts {
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = "1.5.3";
|
||||
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
|
||||
export function findConfigFile(searchPath: string): string {
|
||||
var fileName = "tsconfig.json";
|
||||
while (true) {
|
||||
@@ -94,10 +91,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
let newLine =
|
||||
options.newLine === NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed :
|
||||
options.newLine === NewLineKind.LineFeed ? lineFeed :
|
||||
sys.newLine;
|
||||
const newLine = getNewLineCharacter(options);
|
||||
|
||||
return {
|
||||
getSourceFile,
|
||||
@@ -111,7 +105,10 @@ module ts {
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile): Diagnostic[] {
|
||||
let diagnostics = program.getSyntacticDiagnostics(sourceFile).concat(program.getGlobalDiagnostics()).concat(program.getSemanticDiagnostics(sourceFile));
|
||||
let diagnostics = program.getOptionsDiagnostics().concat(
|
||||
program.getSyntacticDiagnostics(sourceFile),
|
||||
program.getGlobalDiagnostics(),
|
||||
program.getSemanticDiagnostics(sourceFile));
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
diagnostics.concat(program.getDeclarationDiagnostics(sourceFile));
|
||||
@@ -149,20 +146,31 @@ module ts {
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost): Program {
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
let filesByName: Map<SourceFile> = {};
|
||||
let diagnostics = createDiagnosticCollection();
|
||||
let seenNoDefaultLib = options.noLib;
|
||||
|
||||
let commonSourceDirectory: string;
|
||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
let skipDefaultLib = options.noLib;
|
||||
|
||||
let start = new Date().getTime();
|
||||
|
||||
host = host || createCompilerHost(options);
|
||||
forEach(rootNames, name => processRootFile(name, false));
|
||||
if (!seenNoDefaultLib) {
|
||||
processRootFile(host.getDefaultLibFileName(options), true);
|
||||
|
||||
let filesByName = createFileMap<SourceFile>(fileName => host.getCanonicalFileName(fileName));
|
||||
|
||||
forEach(rootNames, name => processRootFile(name, /*isDefaultLib:*/ false));
|
||||
|
||||
// Do not process the default library if:
|
||||
// - The '--noLib' flag is used.
|
||||
// - A 'no-default-lib' reference comment is encountered in
|
||||
// processing the root files.
|
||||
if (!skipDefaultLib) {
|
||||
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib:*/ true);
|
||||
}
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
programTime += new Date().getTime() - start;
|
||||
@@ -172,10 +180,12 @@ module ts {
|
||||
getSourceFiles: () => files,
|
||||
getCompilerOptions: () => options,
|
||||
getSyntacticDiagnostics,
|
||||
getOptionsDiagnostics,
|
||||
getGlobalDiagnostics,
|
||||
getSemanticDiagnostics,
|
||||
getDeclarationDiagnostics,
|
||||
getTypeChecker,
|
||||
getClassifiableNames,
|
||||
getDiagnosticsProducingTypeChecker,
|
||||
getCommonSourceDirectory: () => commonSourceDirectory,
|
||||
emit,
|
||||
@@ -187,6 +197,20 @@ module ts {
|
||||
};
|
||||
return program;
|
||||
|
||||
function getClassifiableNames() {
|
||||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
getTypeChecker();
|
||||
classifiableNames = {};
|
||||
|
||||
for (let sourceFile of files) {
|
||||
copyMap(sourceFile.classifiableNames, classifiableNames);
|
||||
}
|
||||
}
|
||||
|
||||
return classifiableNames;
|
||||
}
|
||||
|
||||
function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost {
|
||||
return {
|
||||
getCanonicalFileName: fileName => host.getCanonicalFileName(fileName),
|
||||
@@ -238,8 +262,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string) {
|
||||
fileName = host.getCanonicalFileName(normalizeSlashes(fileName));
|
||||
return hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined;
|
||||
return filesByName.get(fileName);
|
||||
}
|
||||
|
||||
function getDiagnosticsHelper(sourceFile: SourceFile, getDiagnostics: (sourceFile: SourceFile) => Diagnostic[]): Diagnostic[] {
|
||||
@@ -291,13 +314,15 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
let typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
let allDiagnostics: Diagnostic[] = [];
|
||||
addRange(allDiagnostics, typeChecker.getGlobalDiagnostics());
|
||||
addRange(allDiagnostics, diagnostics.getGlobalDiagnostics());
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
let allDiagnostics: Diagnostic[] = [];
|
||||
addRange(allDiagnostics, getDiagnosticsProducingTypeChecker().getGlobalDiagnostics());
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
}
|
||||
|
||||
@@ -334,14 +359,17 @@ module ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (options.allowNonTsExtensions && !findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
fileName += ".ts";
|
||||
diagnosticArgument = [fileName];
|
||||
var nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, isDefaultLib, refFile, refPos, refEnd);
|
||||
if (!nonTsFile) {
|
||||
if (options.allowNonTsExtensions) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
fileName += ".ts";
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,19 +386,19 @@ module ts {
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
|
||||
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
|
||||
if (hasProperty(filesByName, canonicalName)) {
|
||||
if (filesByName.contains(canonicalName)) {
|
||||
// We've already looked for this file, use cached result
|
||||
return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false);
|
||||
}
|
||||
else {
|
||||
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
|
||||
let canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
|
||||
if (hasProperty(filesByName, canonicalAbsolutePath)) {
|
||||
if (filesByName.contains(canonicalAbsolutePath)) {
|
||||
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
|
||||
}
|
||||
|
||||
// We haven't looked for this file, do so now and cache result
|
||||
let file = filesByName[canonicalName] = host.getSourceFile(fileName, options.target, hostErrorMessage => {
|
||||
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
|
||||
if (refFile) {
|
||||
diagnostics.add(createFileDiagnostic(refFile, refStart, refLength,
|
||||
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
@@ -379,11 +407,12 @@ module ts {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
}
|
||||
});
|
||||
filesByName.set(canonicalName, file);
|
||||
if (file) {
|
||||
seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib;
|
||||
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
|
||||
|
||||
// Set the source file for normalized absolute path
|
||||
filesByName[canonicalAbsolutePath] = file;
|
||||
filesByName.set(canonicalAbsolutePath, file);
|
||||
|
||||
if (!options.noResolve) {
|
||||
let basePath = getDirectoryPath(fileName);
|
||||
@@ -391,6 +420,7 @@ module ts {
|
||||
processImportedModules(file, basePath);
|
||||
}
|
||||
if (isDefaultLib) {
|
||||
file.isDefaultLib = true;
|
||||
files.unshift(file);
|
||||
}
|
||||
else {
|
||||
@@ -402,7 +432,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getSourceFileFromCache(fileName: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
|
||||
let file = filesByName[canonicalName];
|
||||
let file = filesByName.get(canonicalName);
|
||||
if (file && host.useCaseSensitiveFileNames()) {
|
||||
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
|
||||
if (canonicalName !== sourceFileName) {
|
||||
@@ -647,4 +677,4 @@ module ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-2
@@ -1,7 +1,7 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="diagnosticInformationMap.generated.ts"/>
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ErrorCallback {
|
||||
(message: DiagnosticMessage, length: number): void;
|
||||
}
|
||||
@@ -72,6 +72,7 @@ module ts {
|
||||
"in": SyntaxKind.InKeyword,
|
||||
"instanceof": SyntaxKind.InstanceOfKeyword,
|
||||
"interface": SyntaxKind.InterfaceKeyword,
|
||||
"is": SyntaxKind.IsKeyword,
|
||||
"let": SyntaxKind.LetKeyword,
|
||||
"module": SyntaxKind.ModuleKeyword,
|
||||
"namespace": SyntaxKind.NamespaceKeyword,
|
||||
@@ -375,8 +376,31 @@ module ts {
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._7;
|
||||
}
|
||||
|
||||
export function couldStartTrivia(text: string, pos: number): boolean {
|
||||
// Keep in sync with skipTrivia
|
||||
let ch = text.charCodeAt(pos);
|
||||
switch (ch) {
|
||||
case CharacterCodes.carriageReturn:
|
||||
case CharacterCodes.lineFeed:
|
||||
case CharacterCodes.tab:
|
||||
case CharacterCodes.verticalTab:
|
||||
case CharacterCodes.formFeed:
|
||||
case CharacterCodes.space:
|
||||
case CharacterCodes.slash:
|
||||
// starts of normal trivia
|
||||
case CharacterCodes.lessThan:
|
||||
case CharacterCodes.equals:
|
||||
case CharacterCodes.greaterThan:
|
||||
// Starts of conflict marker trivia
|
||||
return true;
|
||||
default:
|
||||
return ch > CharacterCodes.maxAsciiCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
|
||||
// Keep in sync with couldStartTrivia
|
||||
while (true) {
|
||||
let ch = text.charCodeAt(pos);
|
||||
switch (ch) {
|
||||
@@ -933,7 +957,7 @@ module ts {
|
||||
error(Diagnostics.Unexpected_end_of_text);
|
||||
isInvalidExtendedEscape = true;
|
||||
}
|
||||
else if (text.charCodeAt(pos) == CharacterCodes.closeBrace) {
|
||||
else if (text.charCodeAt(pos) === CharacterCodes.closeBrace) {
|
||||
// Only swallow the following character up if it's a '}'.
|
||||
pos++;
|
||||
}
|
||||
|
||||
+32
-16
@@ -1,6 +1,6 @@
|
||||
/// <reference path="core.ts"/>
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
@@ -15,7 +15,7 @@ module ts {
|
||||
createDirectory(path: string): void;
|
||||
getExecutingFilePath(): string;
|
||||
getCurrentDirectory(): string;
|
||||
readDirectory(path: string, extension?: string): string[];
|
||||
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
}
|
||||
@@ -109,7 +109,11 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getNames(collection: any): string[] {
|
||||
function getCanonicalPath(path: string): string {
|
||||
return path.toLowerCase();
|
||||
}
|
||||
|
||||
function getNames(collection: any): string[]{
|
||||
var result: string[] = [];
|
||||
for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
|
||||
result.push(e.item().Name);
|
||||
@@ -117,21 +121,26 @@ module ts {
|
||||
return result.sort();
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extension?: string): string[] {
|
||||
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
||||
var result: string[] = [];
|
||||
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
||||
visitDirectory(path);
|
||||
return result;
|
||||
function visitDirectory(path: string) {
|
||||
var folder = fso.GetFolder(path || ".");
|
||||
var files = getNames(folder.files);
|
||||
for (let name of files) {
|
||||
if (!extension || fileExtensionIs(name, extension)) {
|
||||
result.push(combinePaths(path, name));
|
||||
for (let current of files) {
|
||||
let name = combinePaths(path, current);
|
||||
if ((!extension || fileExtensionIs(name, extension)) && !contains(exclude, getCanonicalPath(name))) {
|
||||
result.push(name);
|
||||
}
|
||||
}
|
||||
var subfolders = getNames(folder.subfolders);
|
||||
for (let current of subfolders) {
|
||||
visitDirectory(combinePaths(path, current));
|
||||
let name = combinePaths(path, current);
|
||||
if (!contains(exclude, getCanonicalPath(name))) {
|
||||
visitDirectory(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,8 +231,13 @@ module ts {
|
||||
_fs.writeFileSync(fileName, data, "utf8");
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extension?: string): string[] {
|
||||
function getCanonicalPath(path: string): string {
|
||||
return useCaseSensitiveFileNames ? path.toLowerCase() : path;
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extension?: string, exclude?: string[]): string[] {
|
||||
var result: string[] = [];
|
||||
exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s)));
|
||||
visitDirectory(path);
|
||||
return result;
|
||||
function visitDirectory(path: string) {
|
||||
@@ -231,14 +245,16 @@ module ts {
|
||||
var directories: string[] = [];
|
||||
for (let current of files) {
|
||||
var name = combinePaths(path, current);
|
||||
var stat = _fs.statSync(name);
|
||||
if (stat.isFile()) {
|
||||
if (!extension || fileExtensionIs(name, extension)) {
|
||||
result.push(name);
|
||||
if (!contains(exclude, getCanonicalPath(name))) {
|
||||
var stat = _fs.statSync(name);
|
||||
if (stat.isFile()) {
|
||||
if (!extension || fileExtensionIs(name, extension)) {
|
||||
result.push(name);
|
||||
}
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
directories.push(name);
|
||||
}
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
directories.push(name);
|
||||
}
|
||||
}
|
||||
for (let current of directories) {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="commandLineParser.ts"/>
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface SourceFile {
|
||||
fileWatcher: FileWatcher;
|
||||
}
|
||||
|
||||
+83
-40
@@ -1,8 +1,16 @@
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface Map<T> {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
export interface FileMap<T> {
|
||||
get(fileName: string): T;
|
||||
set(fileName: string, value: T): void;
|
||||
contains(fileName: string): boolean;
|
||||
remove(fileName: string): void;
|
||||
forEachValue(f: (v: T) => void): void;
|
||||
}
|
||||
|
||||
export interface TextRange {
|
||||
pos: number;
|
||||
end: number;
|
||||
@@ -137,6 +145,7 @@ module ts {
|
||||
ConstructorKeyword,
|
||||
DeclareKeyword,
|
||||
GetKeyword,
|
||||
IsKeyword,
|
||||
ModuleKeyword,
|
||||
NamespaceKeyword,
|
||||
RequireKeyword,
|
||||
@@ -169,6 +178,7 @@ module ts {
|
||||
ConstructSignature,
|
||||
IndexSignature,
|
||||
// Type
|
||||
TypePredicate,
|
||||
TypeReference,
|
||||
FunctionType,
|
||||
ConstructorType,
|
||||
@@ -352,10 +362,6 @@ module ts {
|
||||
export const enum ParserContextFlags {
|
||||
None = 0,
|
||||
|
||||
// Set if this node was parsed in strict mode. Used for grammar error checks, as well as
|
||||
// checking if the node can be reused in incremental settings.
|
||||
StrictMode = 1 << 0,
|
||||
|
||||
// If this node was parsed in a context where 'in-expressions' are not allowed.
|
||||
DisallowIn = 1 << 1,
|
||||
|
||||
@@ -378,7 +384,7 @@ module ts {
|
||||
JavaScriptFile = 1 << 6,
|
||||
|
||||
// Context flags set directly by the parser.
|
||||
ParserGeneratedFlags = StrictMode | DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError,
|
||||
ParserGeneratedFlags = DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError,
|
||||
|
||||
// Context flags computed by aggregating child flags upwards.
|
||||
|
||||
@@ -606,6 +612,11 @@ module ts {
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
}
|
||||
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
parameterName: Identifier;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface TypeQueryNode extends TypeNode {
|
||||
exprName: EntityName;
|
||||
}
|
||||
@@ -793,7 +804,7 @@ module ts {
|
||||
expression: UnaryExpression;
|
||||
}
|
||||
|
||||
export interface Statement extends Node, ModuleElement {
|
||||
export interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
}
|
||||
|
||||
@@ -896,10 +907,6 @@ module ts {
|
||||
block: Block;
|
||||
}
|
||||
|
||||
export interface ModuleElement extends Node {
|
||||
_moduleElementBrand: any;
|
||||
}
|
||||
|
||||
export interface ClassLikeDeclaration extends Declaration {
|
||||
name?: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -931,6 +938,7 @@ module ts {
|
||||
|
||||
export interface TypeAliasDeclaration extends Declaration, Statement {
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
@@ -946,16 +954,16 @@ module ts {
|
||||
members: NodeArray<EnumMember>;
|
||||
}
|
||||
|
||||
export interface ModuleDeclaration extends Declaration, ModuleElement {
|
||||
export interface ModuleDeclaration extends Declaration, Statement {
|
||||
name: Identifier | LiteralExpression;
|
||||
body: ModuleBlock | ModuleDeclaration;
|
||||
}
|
||||
|
||||
export interface ModuleBlock extends Node, ModuleElement {
|
||||
statements: NodeArray<ModuleElement>
|
||||
export interface ModuleBlock extends Node, Statement {
|
||||
statements: NodeArray<Statement>
|
||||
}
|
||||
|
||||
export interface ImportEqualsDeclaration extends Declaration, ModuleElement {
|
||||
export interface ImportEqualsDeclaration extends Declaration, Statement {
|
||||
name: Identifier;
|
||||
|
||||
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
|
||||
@@ -971,7 +979,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 ModuleElement {
|
||||
export interface ImportDeclaration extends Statement {
|
||||
importClause?: ImportClause;
|
||||
moduleSpecifier: Expression;
|
||||
}
|
||||
@@ -991,7 +999,7 @@ module ts {
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
export interface ExportDeclaration extends Declaration, ModuleElement {
|
||||
export interface ExportDeclaration extends Declaration, Statement {
|
||||
exportClause?: NamedExports;
|
||||
moduleSpecifier?: Expression;
|
||||
}
|
||||
@@ -1011,7 +1019,7 @@ module ts {
|
||||
export type ImportSpecifier = ImportOrExportSpecifier;
|
||||
export type ExportSpecifier = ImportOrExportSpecifier;
|
||||
|
||||
export interface ExportAssignment extends Declaration, ModuleElement {
|
||||
export interface ExportAssignment extends Declaration, Statement {
|
||||
isExportEquals?: boolean;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1127,23 +1135,32 @@ module ts {
|
||||
|
||||
// Source files are declarations when they are external modules.
|
||||
export interface SourceFile extends Declaration {
|
||||
statements: NodeArray<ModuleElement>;
|
||||
statements: NodeArray<Statement>;
|
||||
endOfFileToken: Node;
|
||||
|
||||
fileName: string;
|
||||
text: string;
|
||||
|
||||
amdDependencies: {path: string; name: string}[];
|
||||
amdModuleName: string;
|
||||
moduleName: string;
|
||||
referencedFiles: FileReference[];
|
||||
|
||||
/**
|
||||
* lib.d.ts should have a reference comment like
|
||||
*
|
||||
* /// <reference no-default-lib="true"/>
|
||||
*
|
||||
* If any other file has this comment, it signals not to include lib.d.ts
|
||||
* because this containing file is intended to act as a default library.
|
||||
*/
|
||||
hasNoDefaultLib: boolean;
|
||||
|
||||
languageVersion: ScriptTarget;
|
||||
|
||||
// The first node that causes this file to be an external module
|
||||
/* @internal */ externalModuleIndicator: Node;
|
||||
|
||||
|
||||
/* @internal */ isDefaultLib: boolean;
|
||||
/* @internal */ identifiers: Map<string>;
|
||||
/* @internal */ nodeCount: number;
|
||||
/* @internal */ identifierCount: number;
|
||||
@@ -1159,6 +1176,8 @@ module ts {
|
||||
// Stores a line map for the file.
|
||||
// This field should never be used directly to obtain line map, use getLineMap function instead.
|
||||
/* @internal */ lineMap: number[];
|
||||
|
||||
/* @internal */ classifiableNames?: Map<string>;
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
@@ -1168,7 +1187,7 @@ module ts {
|
||||
}
|
||||
|
||||
export interface ParseConfigHost {
|
||||
readDirectory(rootDir: string, extension: string): string[];
|
||||
readDirectory(rootDir: string, extension: string, exclude: string[]): string[];
|
||||
}
|
||||
|
||||
export interface WriteFileCallback {
|
||||
@@ -1193,8 +1212,9 @@ module ts {
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult;
|
||||
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
getOptionsDiagnostics(): Diagnostic[];
|
||||
getGlobalDiagnostics(): Diagnostic[];
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile): Diagnostic[];
|
||||
|
||||
@@ -1209,6 +1229,8 @@ module ts {
|
||||
// language service).
|
||||
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
|
||||
|
||||
/* @internal */ getClassifiableNames(): Map<string>;
|
||||
|
||||
/* @internal */ getNodeCount(): number;
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
/* @internal */ getSymbolCount(): number;
|
||||
@@ -1376,6 +1398,12 @@ module ts {
|
||||
NotAccessible,
|
||||
CannotBeNamed
|
||||
}
|
||||
|
||||
export interface TypePredicate {
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
|
||||
@@ -1396,7 +1424,10 @@ module ts {
|
||||
/* @internal */
|
||||
export interface EmitResolver {
|
||||
hasGlobalName(name: string): boolean;
|
||||
getExpressionNameSubstitution(node: Identifier, getGeneratedNameForNode: (node: Node) => string): string;
|
||||
getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration;
|
||||
getReferencedImportDeclaration(node: Identifier): Declaration;
|
||||
getReferencedNestedRedeclaration(node: Identifier): Declaration;
|
||||
isNestedRedeclaration(node: Declaration): boolean;
|
||||
isValueAliasDeclaration(node: Node): boolean;
|
||||
isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean;
|
||||
isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean;
|
||||
@@ -1411,12 +1442,11 @@ module ts {
|
||||
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;
|
||||
getReferencedValueDeclaration(reference: Identifier): Declaration;
|
||||
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[];
|
||||
serializeTypeOfNode(node: Node): string | string[];
|
||||
serializeParameterTypesOfNode(node: Node): (string | string[])[];
|
||||
serializeReturnTypeOfNode(node: Node): string | string[];
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -1493,8 +1523,15 @@ module ts {
|
||||
HasExports = Class | Enum | Module,
|
||||
HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,
|
||||
|
||||
BlockScoped = BlockScopedVariable | Class | Enum,
|
||||
|
||||
PropertyOrAccessor = Property | Accessor,
|
||||
Export = ExportNamespace | ExportType | ExportValue,
|
||||
|
||||
/* @internal */
|
||||
// The set of things we consider semantically classifiable. Used to speed up the LS during
|
||||
// classification.
|
||||
Classifiable = Class | Enum | TypeAlias | Interface | TypeParameter | Module,
|
||||
}
|
||||
|
||||
export interface Symbol {
|
||||
@@ -1516,12 +1553,15 @@ module ts {
|
||||
export interface SymbolLinks {
|
||||
target?: Symbol; // Resolved (non-alias) target of an alias
|
||||
type?: Type; // Type of value symbol
|
||||
declaredType?: Type; // Type of class, interface, enum, or type parameter
|
||||
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
|
||||
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
|
||||
instantiations?: Map<Type>; // Instantiations of generic type alias (undefined if non-generic)
|
||||
mapper?: TypeMapper; // Type mapper for instantiation alias
|
||||
referenced?: boolean; // True if alias symbol has been referenced as a value
|
||||
unionType?: UnionType; // Containing union type for union property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
exportsChecked?: boolean; // True if exports of external module have been checked
|
||||
isNestedRedeclaration?: boolean; // True if symbol is block scoped redeclaration
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -1582,14 +1622,15 @@ module ts {
|
||||
Tuple = 0x00002000, // Tuple
|
||||
Union = 0x00004000, // Union
|
||||
Anonymous = 0x00008000, // Anonymous
|
||||
Instantiated = 0x00010000, // Instantiated anonymous type
|
||||
/* @internal */
|
||||
FromSignature = 0x00010000, // Created for signature assignment check
|
||||
ObjectLiteral = 0x00020000, // Originates in an object literal
|
||||
FromSignature = 0x00020000, // Created for signature assignment check
|
||||
ObjectLiteral = 0x00040000, // Originates in an object literal
|
||||
/* @internal */
|
||||
ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type
|
||||
ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6
|
||||
ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type
|
||||
ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6
|
||||
|
||||
/* @internal */
|
||||
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
|
||||
@@ -1628,10 +1669,8 @@ module ts {
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
|
||||
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
|
||||
}
|
||||
|
||||
export interface InterfaceTypeWithBaseTypes extends InterfaceType {
|
||||
baseTypes: ObjectType[];
|
||||
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
|
||||
resolvedBaseTypes: ObjectType[]; // Resolved base types
|
||||
}
|
||||
|
||||
export interface InterfaceTypeWithDeclaredMembers extends InterfaceType {
|
||||
@@ -1703,6 +1742,7 @@ module ts {
|
||||
declaration: SignatureDeclaration; // Originating declaration
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
parameters: Symbol[]; // Parameters
|
||||
typePredicate?: TypePredicate; // Type predicate
|
||||
/* @internal */
|
||||
resolvedReturnType: Type; // Resolved return type
|
||||
/* @internal */
|
||||
@@ -1731,7 +1771,6 @@ module ts {
|
||||
/* @internal */
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
mappings?: Map<Type>; // Type mapping cache
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -1823,6 +1862,10 @@ module ts {
|
||||
experimentalDecorators?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
|
||||
// Skip checking lib.d.ts to help speed up tests.
|
||||
/* @internal */ skipDefaultLibCheck?: boolean;
|
||||
|
||||
[option: string]: string | number | boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="binder.ts" />
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ReferencePathMatchResult {
|
||||
fileReference?: FileReference
|
||||
diagnosticMessage?: DiagnosticMessage
|
||||
@@ -42,7 +42,7 @@ module ts {
|
||||
// Pool writers to avoid needing to allocate them for every symbol we write.
|
||||
let stringWriters: StringSymbolWriter[] = [];
|
||||
export function getSingleLineStringWriter(): StringSymbolWriter {
|
||||
if (stringWriters.length == 0) {
|
||||
if (stringWriters.length === 0) {
|
||||
let str = "";
|
||||
|
||||
let writeText: (text: string) => void = text => str += text;
|
||||
@@ -426,7 +426,7 @@ module ts {
|
||||
// Specialized signatures can have string literals as their parameters' type names
|
||||
return node.parent.kind === SyntaxKind.Parameter;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return true;
|
||||
return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
|
||||
|
||||
// Identifiers and qualified names may be type nodes, depending on their context. Climb
|
||||
// above them to find the lowest container
|
||||
@@ -460,7 +460,7 @@ module ts {
|
||||
}
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return true;
|
||||
return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
case SyntaxKind.TypeParameter:
|
||||
return node === (<TypeParameterDeclaration>parent).constraint;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
@@ -872,7 +872,6 @@ module ts {
|
||||
while (node.parent.kind === SyntaxKind.QualifiedName) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeQuery;
|
||||
case SyntaxKind.Identifier:
|
||||
if (node.parent.kind === SyntaxKind.TypeQuery) {
|
||||
@@ -920,6 +919,8 @@ module ts {
|
||||
return node === (<ComputedPropertyName>parent).expression;
|
||||
case SyntaxKind.Decorator:
|
||||
return true;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
default:
|
||||
if (isExpression(parent)) {
|
||||
return true;
|
||||
@@ -1177,6 +1178,41 @@ module ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if the given identifier is classified as an IdentifierName
|
||||
export function isIdentifierName(node: Identifier): boolean {
|
||||
let parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
// Name in member declaration or property name in property access
|
||||
return (<Declaration | PropertyAccessExpression>parent).name === node;
|
||||
case SyntaxKind.QualifiedName:
|
||||
// Name on right hand side of dot in a type query
|
||||
if ((<QualifiedName>parent).right === node) {
|
||||
while (parent.kind === SyntaxKind.QualifiedName) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
return parent.kind === SyntaxKind.TypeQuery;
|
||||
}
|
||||
return false;
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
// Property name in binding element or import specifier
|
||||
return (<BindingElement | ImportSpecifier>parent).propertyName === node;
|
||||
case SyntaxKind.ExportSpecifier:
|
||||
// Any name in an export specifier
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// An alias symbol is created by one of the following declarations:
|
||||
// import <symbol> = ...
|
||||
// import <symbol> from ...
|
||||
@@ -1878,6 +1914,12 @@ module ts {
|
||||
return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments &&
|
||||
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword &&
|
||||
node.parent.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
}
|
||||
|
||||
// Returns false if this heritage clause element's expression contains something unsupported
|
||||
// (i.e. not a name or dotted name).
|
||||
export function isSupportedExpressionWithTypeArguments(node: ExpressionWithTypeArguments): boolean {
|
||||
@@ -1985,9 +2027,24 @@ module ts {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
export function getNewLineCharacter(options: CompilerOptions): string {
|
||||
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
|
||||
return carriageReturnLineFeed;
|
||||
}
|
||||
else if (options.newLine === NewLineKind.LineFeed) {
|
||||
return lineFeed;
|
||||
}
|
||||
else if (sys) {
|
||||
return sys.newLine
|
||||
}
|
||||
return carriageReturnLineFeed;
|
||||
}
|
||||
}
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
export function getDefaultLibFileName(options: CompilerOptions): string {
|
||||
return options.target === ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts";
|
||||
}
|
||||
@@ -2033,6 +2090,12 @@ module ts {
|
||||
return start <= textSpanEnd(span) && end >= span.start;
|
||||
}
|
||||
|
||||
export function decodedTextSpanIntersectsWith(start1: number, length1: number, start2: number, length2: number) {
|
||||
let end1 = start1 + length1;
|
||||
let end2 = start2 + length2;
|
||||
return start2 <= end1 && end2 >= start1;
|
||||
}
|
||||
|
||||
export function textSpanIntersectsWithPosition(span: TextSpan, position: number) {
|
||||
return position <= textSpanEnd(span) && position >= span.start;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path='typeWriter.ts' />
|
||||
/// <reference path='syntacticCleaner.ts' />
|
||||
|
||||
const enum CompilerTestType {
|
||||
Conformance,
|
||||
@@ -18,7 +17,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
public options: string;
|
||||
|
||||
constructor(public testType?: CompilerTestType) {
|
||||
constructor(public testType: CompilerTestType) {
|
||||
super();
|
||||
this.errors = true;
|
||||
this.emit = true;
|
||||
@@ -171,7 +170,6 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('Correct JS output for ' + fileName, () => {
|
||||
if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) {
|
||||
if (result.files.length === 0 && result.errors.length === 0) {
|
||||
@@ -195,8 +193,6 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n';
|
||||
jsCode += getByteOrderMarkText(result.files[i]);
|
||||
jsCode += result.files[i].code;
|
||||
// Re-enable this if we want to do another comparison of old vs new compiler baselines
|
||||
// jsCode += SyntacticCleaner.clean(result.files[i].code);
|
||||
}
|
||||
|
||||
if (result.declFilesCode.length > 0) {
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Allows for executing a program with command-line arguments and reading the result
|
||||
interface IExec {
|
||||
exec: (fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) => void;
|
||||
}
|
||||
|
||||
class ExecResult {
|
||||
public stdout = "";
|
||||
public stderr = "";
|
||||
public exitCode: number;
|
||||
}
|
||||
|
||||
class WindowsScriptHostExec implements IExec {
|
||||
public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void {
|
||||
var result = new ExecResult();
|
||||
var shell = new ActiveXObject('WScript.Shell');
|
||||
try {
|
||||
var process = shell.Exec(fileName + ' ' + cmdLineArgs.join(' '));
|
||||
} catch(e) {
|
||||
result.stderr = e.message;
|
||||
result.exitCode = 1;
|
||||
handleResult(result);
|
||||
return;
|
||||
}
|
||||
// Wait for it to finish running
|
||||
while (process.Status != 0) { /* todo: sleep? */ }
|
||||
|
||||
|
||||
result.exitCode = process.ExitCode;
|
||||
if(!process.StdOut.AtEndOfStream) result.stdout = process.StdOut.ReadAll();
|
||||
if(!process.StdErr.AtEndOfStream) result.stderr = process.StdErr.ReadAll();
|
||||
|
||||
handleResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
class NodeExec implements IExec {
|
||||
public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void {
|
||||
var nodeExec = require('child_process').exec;
|
||||
|
||||
var result = new ExecResult();
|
||||
result.exitCode = null;
|
||||
var cmdLine = fileName + ' ' + cmdLineArgs.join(' ');
|
||||
var process = nodeExec(cmdLine, function(error: any, stdout: string, stderr: string) {
|
||||
result.stdout = stdout;
|
||||
result.stderr = stderr;
|
||||
result.exitCode = error ? error.code : 0;
|
||||
handleResult(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var Exec: IExec = function() : IExec {
|
||||
var global = <any>Function("return this;").call(null);
|
||||
if(typeof global.ActiveXObject !== "undefined") {
|
||||
return new WindowsScriptHostExec();
|
||||
} else {
|
||||
return new NodeExec();
|
||||
}
|
||||
}();
|
||||
@@ -343,7 +343,8 @@ module FourSlash {
|
||||
if (!resolvedResult.isLibFile) {
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// resolveReference file-option is not specified then do not resolve any files and include all inputFiles
|
||||
ts.forEachKey(this.inputFiles, fileName => {
|
||||
if (!Harness.isLibraryFile(fileName)) {
|
||||
@@ -830,6 +831,7 @@ module FourSlash {
|
||||
if (expectedText !== undefined) {
|
||||
assert.notEqual(actualQuickInfoText, expectedText, this.messageAtLastKnownMarker("quick info text"));
|
||||
}
|
||||
// TODO: should be '==='?
|
||||
if (expectedDocumentation != undefined) {
|
||||
assert.notEqual(actualQuickInfoDocumentation, expectedDocumentation, this.messageAtLastKnownMarker("quick info doc comment"));
|
||||
}
|
||||
@@ -837,6 +839,7 @@ module FourSlash {
|
||||
if (expectedText !== undefined) {
|
||||
assert.equal(actualQuickInfoText, expectedText, this.messageAtLastKnownMarker("quick info text"));
|
||||
}
|
||||
// TODO: should be '==='?
|
||||
if (expectedDocumentation != undefined) {
|
||||
assert.equal(actualQuickInfoDocumentation, expectedDocumentation, assertionMessage("quick info doc"));
|
||||
}
|
||||
@@ -1825,7 +1828,7 @@ module FourSlash {
|
||||
}
|
||||
|
||||
private verifyProjectInfo(expected: string[]) {
|
||||
if (this.testType == FourSlashTestType.Server) {
|
||||
if (this.testType === FourSlashTestType.Server) {
|
||||
let actual = (<ts.server.SessionClient>this.languageService).getProjectInfo(
|
||||
this.activeFile.fileName,
|
||||
/* needFileNameList */ true
|
||||
@@ -1942,7 +1945,7 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
if (expected != actual) {
|
||||
if (expected !== actual) {
|
||||
this.raiseError('verifyNavigationItemsCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
}
|
||||
}
|
||||
@@ -1989,7 +1992,7 @@ module FourSlash {
|
||||
var items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
|
||||
var actual = this.getNavigationBarItemsCount(items);
|
||||
|
||||
if (expected != actual) {
|
||||
if (expected !== actual) {
|
||||
this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
|
||||
}
|
||||
}
|
||||
@@ -2407,6 +2410,7 @@ module FourSlash {
|
||||
globalOptions[match[1]] = match[2];
|
||||
}
|
||||
}
|
||||
// TODO: should be '==='?
|
||||
} else if (line == '' || lineLength === 0) {
|
||||
// Previously blank lines between fourslash content caused it to be considered as 2 files,
|
||||
// Remove this behavior since it just causes errors now
|
||||
|
||||
+114
-150
@@ -99,7 +99,7 @@ module Utils {
|
||||
}
|
||||
|
||||
try {
|
||||
var content = ts.sys.readFile(Harness.userSpecifiedroot + path);
|
||||
var content = ts.sys.readFile(Harness.userSpecifiedRoot + path);
|
||||
}
|
||||
catch (err) {
|
||||
return undefined;
|
||||
@@ -732,7 +732,8 @@ module Harness {
|
||||
}
|
||||
|
||||
// Settings
|
||||
export var userSpecifiedroot = "";
|
||||
export let userSpecifiedRoot = "";
|
||||
export let lightMode = false;
|
||||
|
||||
/** Functionality for compiling TypeScript code */
|
||||
export module Compiler {
|
||||
@@ -808,12 +809,20 @@ module Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function createSourceFileAndAssertInvariants(fileName: string, sourceText: string, languageVersion: ts.ScriptTarget, assertInvariants = true) {
|
||||
export function createSourceFileAndAssertInvariants(
|
||||
fileName: string,
|
||||
sourceText: string,
|
||||
languageVersion: ts.ScriptTarget) {
|
||||
// We'll only assert invariants outside of light mode.
|
||||
const shouldAssertInvariants = !Harness.lightMode;
|
||||
|
||||
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
|
||||
var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ assertInvariants);
|
||||
if (assertInvariants) {
|
||||
var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
|
||||
|
||||
if (shouldAssertInvariants) {
|
||||
Utils.assertInvariants(result, /*parent:*/ undefined);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -832,13 +841,14 @@ module Harness {
|
||||
return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
export function createCompilerHost(inputFiles: { unitName: string; content: string; }[],
|
||||
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
|
||||
scriptTarget: ts.ScriptTarget,
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory?: string,
|
||||
newLineKind?: ts.NewLineKind): ts.CompilerHost {
|
||||
export function createCompilerHost(
|
||||
inputFiles: { unitName: string; content: string; }[],
|
||||
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
|
||||
scriptTarget: ts.ScriptTarget,
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory?: string,
|
||||
newLineKind?: ts.NewLineKind): ts.CompilerHost {
|
||||
|
||||
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
|
||||
function getCanonicalFileName(fileName: string): string {
|
||||
@@ -899,7 +909,7 @@ module Harness {
|
||||
private compileOptions: ts.CompilerOptions;
|
||||
private settings: Harness.TestCaseParser.CompilerSetting[] = [];
|
||||
|
||||
private lastErrors: HarnessDiagnostic[];
|
||||
private lastErrors: ts.Diagnostic[];
|
||||
|
||||
public reset() {
|
||||
this.inputFiles = [];
|
||||
@@ -932,17 +942,19 @@ module Harness {
|
||||
}
|
||||
|
||||
public emitAll(ioHost?: IEmitterIOHost) {
|
||||
this.compileFiles(this.inputFiles, [],(result) => {
|
||||
result.files.forEach(file => {
|
||||
ioHost.writeFile(file.fileName, file.code, false);
|
||||
});
|
||||
result.declFilesCode.forEach(file => {
|
||||
ioHost.writeFile(file.fileName, file.code, false);
|
||||
});
|
||||
result.sourceMaps.forEach(file => {
|
||||
ioHost.writeFile(file.fileName, file.code, false);
|
||||
});
|
||||
},() => { }, this.compileOptions);
|
||||
this.compileFiles(this.inputFiles,
|
||||
/*otherFiles*/ [],
|
||||
/*onComplete*/ result => {
|
||||
result.files.forEach(writeFile);
|
||||
result.declFilesCode.forEach(writeFile);
|
||||
result.sourceMaps.forEach(writeFile);
|
||||
},
|
||||
/*settingsCallback*/ () => { },
|
||||
this.compileOptions);
|
||||
|
||||
function writeFile(file: GeneratedFile) {
|
||||
ioHost.writeFile(file.fileName, file.code, false);
|
||||
}
|
||||
}
|
||||
|
||||
public compileFiles(inputFiles: { unitName: string; content: string }[],
|
||||
@@ -951,8 +963,7 @@ module Harness {
|
||||
settingsCallback?: (settings: ts.CompilerOptions) => void,
|
||||
options?: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory?: string,
|
||||
assertInvariants = true) {
|
||||
currentDirectory?: string) {
|
||||
|
||||
options = options || { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
@@ -964,14 +975,39 @@ module Harness {
|
||||
settingsCallback(null);
|
||||
}
|
||||
|
||||
var newLine = '\r\n';
|
||||
let newLine = '\r\n';
|
||||
options.skipDefaultLibCheck = true;
|
||||
|
||||
// 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 => {
|
||||
this.settings.forEach(setCompilerOptionForSetting);
|
||||
|
||||
var fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
|
||||
|
||||
var compilerHost = createCompilerHost(
|
||||
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
|
||||
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
|
||||
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
|
||||
var program = ts.createProgram(programFiles, options, compilerHost);
|
||||
|
||||
var emitResult = program.emit();
|
||||
|
||||
var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
this.lastErrors = errors;
|
||||
|
||||
var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
onComplete(result, program);
|
||||
|
||||
// reset what newline means in case the last test changed it
|
||||
ts.sys.newLine = newLine;
|
||||
return options;
|
||||
|
||||
function setCompilerOptionForSetting(setting: Harness.TestCaseParser.CompilerSetting) {
|
||||
switch (setting.flag.toLowerCase()) {
|
||||
// "fileName", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve"
|
||||
case "module":
|
||||
@@ -1050,6 +1086,10 @@ module Harness {
|
||||
options.outDir = setting.value;
|
||||
break;
|
||||
|
||||
case 'skipdefaultlibcheck':
|
||||
options.skipDefaultLibCheck = setting.value === "true";
|
||||
break;
|
||||
|
||||
case 'sourceroot':
|
||||
options.sourceRoot = setting.value;
|
||||
break;
|
||||
@@ -1078,10 +1118,6 @@ module Harness {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'normalizenewline':
|
||||
newLine = setting.value;
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
options.removeComments = setting.value === 'false';
|
||||
break;
|
||||
@@ -1125,7 +1161,7 @@ module Harness {
|
||||
case 'inlinesourcemap':
|
||||
options.inlineSourceMap = setting.value === 'true';
|
||||
break;
|
||||
|
||||
|
||||
case 'inlinesources':
|
||||
options.inlineSources = setting.value === 'true';
|
||||
break;
|
||||
@@ -1133,30 +1169,7 @@ module Harness {
|
||||
default:
|
||||
throw new Error('Unsupported compiler setting ' + setting.flag);
|
||||
}
|
||||
});
|
||||
|
||||
var fileOutputs: GeneratedFile[] = [];
|
||||
|
||||
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, options.newLine));
|
||||
|
||||
var emitResult = program.emit();
|
||||
|
||||
var errors: HarnessDiagnostic[] = [];
|
||||
ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics).forEach(err => {
|
||||
// TODO: new compiler formats errors after this point to add . and newlines so we'll just do it manually for now
|
||||
errors.push(getMinimalDiagnostic(err));
|
||||
});
|
||||
this.lastErrors = errors;
|
||||
|
||||
var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps);
|
||||
onComplete(result, program);
|
||||
|
||||
// reset what newline means in case the last test changed it
|
||||
ts.sys.newLine = newLine;
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
public compileDeclarationFiles(inputFiles: { unitName: string; content: string; }[],
|
||||
@@ -1235,70 +1248,50 @@ module Harness {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function getMinimalDiagnostic(err: ts.Diagnostic): HarnessDiagnostic {
|
||||
var errorLineInfo = err.file ? err.file.getLineAndCharacterOfPosition(err.start) : { line: -1, character: -1 };
|
||||
return {
|
||||
fileName: err.file && err.file.fileName,
|
||||
start: err.start,
|
||||
end: err.start + err.length,
|
||||
line: errorLineInfo.line + 1,
|
||||
character: errorLineInfo.character + 1,
|
||||
message: ts.flattenDiagnosticMessageText(err.messageText, ts.sys.newLine),
|
||||
category: ts.DiagnosticCategory[err.category].toLowerCase(),
|
||||
code: err.code
|
||||
};
|
||||
}
|
||||
|
||||
export function minimalDiagnosticsToString(diagnostics: HarnessDiagnostic[]) {
|
||||
export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) {
|
||||
// This is basically copied from tsc.ts's reportError to replicate what tsc does
|
||||
var errorOutput = "";
|
||||
ts.forEach(diagnostics, diagnotic => {
|
||||
if (diagnotic.fileName) {
|
||||
errorOutput += diagnotic.fileName + "(" + diagnotic.line + "," + diagnotic.character + "): ";
|
||||
ts.forEach(diagnostics, diagnostic => {
|
||||
if (diagnostic.file) {
|
||||
var lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
||||
errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): ";
|
||||
}
|
||||
|
||||
errorOutput += diagnotic.category + " TS" + diagnotic.code + ": " + diagnotic.message + ts.sys.newLine;
|
||||
errorOutput += ts.DiagnosticCategory[diagnostic.category].toLowerCase() + " TS" + diagnostic.code + ": " + ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine) + ts.sys.newLine;
|
||||
});
|
||||
|
||||
return errorOutput;
|
||||
}
|
||||
|
||||
function compareDiagnostics(d1: HarnessDiagnostic, d2: HarnessDiagnostic) {
|
||||
return ts.compareValues(d1.fileName, d2.fileName) ||
|
||||
ts.compareValues(d1.start, d2.start) ||
|
||||
ts.compareValues(d1.end, d2.end) ||
|
||||
ts.compareValues(d1.code, d2.code) ||
|
||||
ts.compareValues(d1.message, d2.message) ||
|
||||
0;
|
||||
}
|
||||
|
||||
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: HarnessDiagnostic[]) {
|
||||
diagnostics.sort(compareDiagnostics);
|
||||
export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) {
|
||||
diagnostics.sort(ts.compareDiagnostics);
|
||||
var outputLines: string[] = [];
|
||||
// Count up all the errors we find so we don't miss any
|
||||
var totalErrorsReported = 0;
|
||||
|
||||
function outputErrorText(error: Harness.Compiler.HarnessDiagnostic) {
|
||||
var errLines = RunnerBase.removeFullPaths(error.message)
|
||||
function outputErrorText(error: ts.Diagnostic) {
|
||||
var message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine);
|
||||
|
||||
var errLines = RunnerBase.removeFullPaths(message)
|
||||
.split('\n')
|
||||
.map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s)
|
||||
.filter(s => s.length > 0)
|
||||
.map(s => '!!! ' + error.category + " TS" + error.code + ": " + s);
|
||||
.map(s => '!!! ' + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
|
||||
errLines.forEach(e => outputLines.push(e));
|
||||
|
||||
totalErrorsReported++;
|
||||
}
|
||||
|
||||
// Report global errors
|
||||
var globalErrors = diagnostics.filter(err => !err.fileName);
|
||||
var globalErrors = diagnostics.filter(err => !err.file);
|
||||
globalErrors.forEach(outputErrorText);
|
||||
|
||||
// 'merge' the lines of each input file with any errors associated with it
|
||||
inputFiles.filter(f => f.content !== undefined).forEach(inputFile => {
|
||||
// Filter down to the errors in the file
|
||||
var fileErrors = diagnostics.filter(e => {
|
||||
var errFn = e.fileName;
|
||||
return errFn && errFn === inputFile.unitName;
|
||||
var errFn = e.file;
|
||||
return errFn && errFn.fileName === inputFile.unitName;
|
||||
});
|
||||
|
||||
|
||||
@@ -1334,18 +1327,19 @@ module Harness {
|
||||
outputLines.push(' ' + line);
|
||||
fileErrors.forEach(err => {
|
||||
// Does any error start or continue on to this line? Emit squiggles
|
||||
if ((err.end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
||||
let end = ts.textSpanEnd(err);
|
||||
if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
||||
// How many characters from the start of this line the error starts at (could be positive or negative)
|
||||
var relativeOffset = err.start - thisLineStart;
|
||||
// How many characters of the error are on this line (might be longer than this line in reality)
|
||||
var length = (err.end - err.start) - Math.max(0, thisLineStart - err.start);
|
||||
var length = (end - err.start) - Math.max(0, thisLineStart - err.start);
|
||||
// Calculate the start of the squiggle
|
||||
var squiggleStart = Math.max(0, relativeOffset);
|
||||
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
|
||||
outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~'));
|
||||
|
||||
// If the error ended here, or we're at the end of the file, emit its message
|
||||
if ((lineIndex === lines.length - 1) || nextLineStart > err.end) {
|
||||
if ((lineIndex === lines.length - 1) || nextLineStart > end) {
|
||||
// Just like above, we need to do a split on a string instead of on a regex
|
||||
// because the JS engine does regexes wrong
|
||||
|
||||
@@ -1361,12 +1355,12 @@ module Harness {
|
||||
});
|
||||
|
||||
var numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
return diagnostic.fileName && (isLibraryFile(diagnostic.fileName) || isBuiltFile(diagnostic.fileName));
|
||||
return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||
});
|
||||
|
||||
var numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
// Count an error generated from tests262-harness folder.This should only apply for test262
|
||||
return diagnostic.fileName && diagnostic.fileName.indexOf("test262-harness") >= 0;
|
||||
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
||||
});
|
||||
|
||||
// Verify we didn't miss any errors in total
|
||||
@@ -1376,29 +1370,30 @@ module Harness {
|
||||
ts.sys.newLine + ts.sys.newLine + outputLines.join('\r\n');
|
||||
}
|
||||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[], clean?: (s: string) => string) {
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
// Collect, test, and sort the fileNames
|
||||
function cleanName(fn: string) {
|
||||
var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
|
||||
return fn.substr(lastSlash + 1).toLowerCase();
|
||||
}
|
||||
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
|
||||
|
||||
// Emit them
|
||||
var result = '';
|
||||
ts.forEach(outputFiles, outputFile => {
|
||||
for (let outputFile of outputFiles) {
|
||||
// Some extra spacing if this isn't the first file
|
||||
if (result.length) result = result + '\r\n\r\n';
|
||||
if (result.length) {
|
||||
result += '\r\n\r\n';
|
||||
}
|
||||
|
||||
// FileName header + content
|
||||
result = result + '/*====== ' + outputFile.fileName + ' ======*/\r\n';
|
||||
if (clean) {
|
||||
result = result + clean(outputFile.code);
|
||||
} else {
|
||||
result = result + outputFile.code;
|
||||
}
|
||||
});
|
||||
result += '/*====== ' + outputFile.fileName + ' ======*/\r\n';
|
||||
|
||||
result += outputFile.code;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function cleanName(fn: string) {
|
||||
var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
|
||||
return fn.substr(lastSlash + 1).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */
|
||||
@@ -1419,17 +1414,6 @@ module Harness {
|
||||
//harnessCompiler.compileString(code, unitName, callback);
|
||||
}
|
||||
|
||||
export interface HarnessDiagnostic {
|
||||
fileName: string;
|
||||
start: number;
|
||||
end: number;
|
||||
line: number;
|
||||
character: number;
|
||||
message: string;
|
||||
category: string;
|
||||
code: number;
|
||||
}
|
||||
|
||||
export interface GeneratedFile {
|
||||
fileName: string;
|
||||
code: string;
|
||||
@@ -1459,12 +1443,12 @@ module Harness {
|
||||
/** Contains the code and errors of a compilation and some helper methods to check its status. */
|
||||
export class CompilerResult {
|
||||
public files: GeneratedFile[] = [];
|
||||
public errors: HarnessDiagnostic[] = [];
|
||||
public errors: ts.Diagnostic[] = [];
|
||||
public declFilesCode: GeneratedFile[] = [];
|
||||
public sourceMaps: GeneratedFile[] = [];
|
||||
|
||||
/** @param fileResults an array of strings for the fileName and an ITextWriter with its code */
|
||||
constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], public program: ts.Program,
|
||||
constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program,
|
||||
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) {
|
||||
|
||||
fileResults.forEach(emittedFile => {
|
||||
@@ -1489,15 +1473,6 @@ module Harness {
|
||||
return Harness.SourceMapRecoder.getSourceMapRecord(this.sourceMapData, this.program, this.files);
|
||||
}
|
||||
}
|
||||
|
||||
public isErrorAt(line: number, column: number, message: string) {
|
||||
for (var i = 0; i < this.errors.length; i++) {
|
||||
if ((this.errors[i].line + 1) === line && (this.errors[i].character + 1) === column && this.errors[i].message === message)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,15 +1495,6 @@ module Harness {
|
||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||
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", "noemithelpers", "noemitonerror",
|
||||
"noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom",
|
||||
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
|
||||
"includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal",
|
||||
"isolatedmodules", "inlinesourcemap", "maproot", "sourceroot",
|
||||
"inlinesources", "emitdecoratormetadata", "experimentaldecorators"];
|
||||
|
||||
function extractCompilerSettings(content: string): CompilerSetting[] {
|
||||
|
||||
var opts: CompilerSetting[] = [];
|
||||
@@ -1562,10 +1528,8 @@ module Harness {
|
||||
if (testMetaData) {
|
||||
// Comment line, check for global/file @options and record them
|
||||
optionRegex.lastIndex = 0;
|
||||
var fileNameIndex = fileMetadataNames.indexOf(testMetaData[1].toLowerCase());
|
||||
if (fileNameIndex === -1) {
|
||||
throw new Error('Unrecognized metadata name "' + testMetaData[1] + '". Available file metadata names are: ' + fileMetadataNames.join(', '));
|
||||
} else if (fileNameIndex === 0) {
|
||||
var metaDataName = testMetaData[1].toLowerCase();
|
||||
if (metaDataName === "filename") {
|
||||
currentFileOptions[testMetaData[1]] = testMetaData[2];
|
||||
} else {
|
||||
continue;
|
||||
@@ -1651,9 +1615,9 @@ module Harness {
|
||||
|
||||
function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) {
|
||||
if (subfolder !== undefined) {
|
||||
return Harness.userSpecifiedroot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName;
|
||||
return Harness.userSpecifiedRoot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName;
|
||||
} else {
|
||||
return Harness.userSpecifiedroot + baselineFolder + '/' + type + '/' + fileName;
|
||||
return Harness.userSpecifiedRoot + baselineFolder + '/' + type + '/' + fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1762,7 +1726,7 @@ module Harness {
|
||||
}
|
||||
|
||||
export function getDefaultLibraryFile(): { unitName: string, content: string } {
|
||||
var libFile = Harness.userSpecifiedroot + Harness.libFolder + "/" + "lib.d.ts";
|
||||
var libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts";
|
||||
return {
|
||||
unitName: libFile,
|
||||
content: IO.readFile(libFile)
|
||||
|
||||
@@ -583,7 +583,7 @@ module Harness.LanguageService {
|
||||
// This host is just a proxy for the clientHost, it uses the client
|
||||
// host to answer server queries about files on disk
|
||||
var serverHost = new SessionServerHost(clientHost);
|
||||
var server = new ts.server.Session(serverHost, serverHost);
|
||||
var server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost);
|
||||
|
||||
// Fake the connection between the client and the server
|
||||
serverHost.writeMessage = client.onMessage.bind(client);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
/// <reference path="exec.ts" />
|
||||
/// <reference path="generate.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="diff.ts" />
|
||||
@@ -110,6 +110,7 @@ class ProjectRunner extends RunnerBase {
|
||||
else if (url.indexOf(diskProjectPath) === 0) {
|
||||
// Replace the disk specific path into the project root path
|
||||
url = url.substr(diskProjectPath.length);
|
||||
// TODO: should be '!=='?
|
||||
if (url.charCodeAt(0) != ts.CharacterCodes.slash) {
|
||||
url = "/" + url;
|
||||
}
|
||||
@@ -240,7 +241,7 @@ class ProjectRunner extends RunnerBase {
|
||||
if (Harness.Compiler.isJS(fileName)) {
|
||||
// Make sure if there is URl we have it cleaned up
|
||||
var indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
|
||||
if (indexOfSourceMapUrl != -1) {
|
||||
if (indexOfSourceMapUrl !== -1) {
|
||||
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
|
||||
}
|
||||
}
|
||||
@@ -323,9 +324,8 @@ class ProjectRunner extends RunnerBase {
|
||||
sourceFile => {
|
||||
return { unitName: sourceFile.fileName, content: sourceFile.text };
|
||||
});
|
||||
var diagnostics = ts.map(compilerResult.errors, error => Harness.Compiler.getMinimalDiagnostic(error));
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, diagnostics);
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
var name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName;
|
||||
|
||||
+42
-35
@@ -18,6 +18,7 @@
|
||||
/// <reference path='fourslashRunner.ts' />
|
||||
/// <reference path='projectsRunner.ts' />
|
||||
/// <reference path='rwcRunner.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
|
||||
function runTests(runners: RunnerBase[]) {
|
||||
for (var i = iterations; i > 0; i--) {
|
||||
@@ -38,41 +39,47 @@ var testConfigFile =
|
||||
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');
|
||||
|
||||
if (testConfigFile !== '') {
|
||||
// TODO: not sure why this is crashing mocha
|
||||
//var testConfig = JSON.parse(testConfigRaw);
|
||||
var testConfig = testConfigFile.match(/test:\s\['(.*)'\]/);
|
||||
var options = testConfig ? [testConfig[1]] : [];
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
switch (options[i]) {
|
||||
case 'compiler':
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'conformance':
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
break;
|
||||
case 'project':
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'fourslash':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'fourslash-shims':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case 'fourslash-server':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case 'fourslash-generated':
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'rwc':
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
case 'test262':
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
var testConfig = JSON.parse(testConfigFile);
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
}
|
||||
|
||||
if (testConfig.test && testConfig.test.length > 0) {
|
||||
for (let option of testConfig.test) {
|
||||
if (!option) {
|
||||
continue;
|
||||
}
|
||||
switch (option) {
|
||||
case 'compiler':
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'conformance':
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
break;
|
||||
case 'project':
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case 'fourslash':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'fourslash-shims':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case 'fourslash-server':
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case 'fourslash-generated':
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case 'rwc':
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
case 'test262':
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class RunnerBase {
|
||||
}
|
||||
|
||||
public enumerateFiles(folder: string, regex?: RegExp, options?: { recursive: boolean }): string[] {
|
||||
return Harness.IO.listFiles(Harness.userSpecifiedroot + folder, regex, { recursive: (options ? options.recursive : false) });
|
||||
return Harness.IO.listFiles(Harness.userSpecifiedRoot + folder, regex, { recursive: (options ? options.recursive : false) });
|
||||
}
|
||||
|
||||
/** Setup the runner's tests so that they are ready to be executed by the harness
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path='harness.ts'/>
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path='syntacticCleaner.ts' />
|
||||
/// <reference path='loggedIO.ts' />
|
||||
/// <reference path='..\compiler\commandLineParser.ts'/>
|
||||
|
||||
@@ -75,7 +74,7 @@ module RWC {
|
||||
});
|
||||
|
||||
// Add files to compilation
|
||||
for(let fileRead of ioLog.filesRead) {
|
||||
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);
|
||||
@@ -107,14 +106,14 @@ module RWC {
|
||||
opts.options.noLib = true;
|
||||
|
||||
// Emit the results
|
||||
compilerOptions = harnessCompiler.compileFiles(inputFiles, otherFiles, compileResult => {
|
||||
compilerResult = compileResult;
|
||||
},
|
||||
compilerOptions = harnessCompiler.compileFiles(
|
||||
inputFiles,
|
||||
otherFiles,
|
||||
newCompilerResults => { compilerResult = newCompilerResults; },
|
||||
/*settingsCallback*/ undefined, opts.options,
|
||||
// Since all Rwc json file specified current directory in its json file, we need to pass this information to compilerHost
|
||||
// so that when the host is asked for current directory, it should give the value from json rather than from process
|
||||
currentDirectory,
|
||||
/*assertInvariants:*/ false);
|
||||
// Since each RWC json file specifies its current directory in its json file, we need
|
||||
// to pass this information in explicitly instead of acquiring it from the process.
|
||||
currentDirectory);
|
||||
});
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string) {
|
||||
@@ -132,7 +131,7 @@ module RWC {
|
||||
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
|
||||
return Harness.Compiler.collateOutputs(compilerResult.files, s => SyntacticCleaner.clean(s));
|
||||
return Harness.Compiler.collateOutputs(compilerResult.files);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
function isSourceMappingSegmentEnd() {
|
||||
if (decodingIndex == sourceMapMappings.length) {
|
||||
if (decodingIndex === sourceMapMappings.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ module Harness.SourceMapRecoder {
|
||||
var currentByte = base64FormatDecode();
|
||||
|
||||
// If msb is set, we still have more bits to continue
|
||||
moreDigits = (currentByte & 32) != 0;
|
||||
moreDigits = (currentByte & 32) !== 0;
|
||||
|
||||
// least significant 5 bits are the next msbs in the final value.
|
||||
value = value | ((currentByte & 31) << shiftCount);
|
||||
@@ -103,7 +103,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
// Least significant bit if 1 represents negative and rest of the msb is actual absolute value
|
||||
if ((value & 1) == 0) {
|
||||
if ((value & 1) === 0) {
|
||||
// + number
|
||||
value = value >> 1;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
}
|
||||
// Dont support reading mappings that dont have information about original source and its line numbers
|
||||
if (createErrorIfCondition(!isSourceMappingSegmentEnd(), "Unsupported Error Format: There are more entries after " + (decodeOfEncodedMapping.nameIndex == -1 ? "sourceColumn" : "nameIndex"))) {
|
||||
if (createErrorIfCondition(!isSourceMappingSegmentEnd(), "Unsupported Error Format: There are more entries after " + (decodeOfEncodedMapping.nameIndex === -1 ? "sourceColumn" : "nameIndex"))) {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ module Harness.SourceMapRecoder {
|
||||
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
|
||||
}
|
||||
else {
|
||||
if (mapEntry.nameIndex != -1 || getAbsentNameIndex) {
|
||||
if (mapEntry.nameIndex !== -1 || getAbsentNameIndex) {
|
||||
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
|
||||
}
|
||||
}
|
||||
@@ -262,12 +262,12 @@ module Harness.SourceMapRecoder {
|
||||
var decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
var decodedErrors: string[];
|
||||
if (decodeResult.error
|
||||
|| decodeResult.sourceMapSpan.emittedLine != sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn != sourceMapSpan.emittedColumn
|
||||
|| decodeResult.sourceMapSpan.sourceLine != sourceMapSpan.sourceLine
|
||||
|| decodeResult.sourceMapSpan.sourceColumn != sourceMapSpan.sourceColumn
|
||||
|| decodeResult.sourceMapSpan.sourceIndex != sourceMapSpan.sourceIndex
|
||||
|| decodeResult.sourceMapSpan.nameIndex != sourceMapSpan.nameIndex) {
|
||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|
||||
|| decodeResult.sourceMapSpan.sourceLine !== sourceMapSpan.sourceLine
|
||||
|| decodeResult.sourceMapSpan.sourceColumn !== sourceMapSpan.sourceColumn
|
||||
|| decodeResult.sourceMapSpan.sourceIndex !== sourceMapSpan.sourceIndex
|
||||
|| decodeResult.sourceMapSpan.nameIndex !== sourceMapSpan.nameIndex) {
|
||||
if (decodeResult.error) {
|
||||
decodedErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
|
||||
}
|
||||
@@ -288,7 +288,7 @@ module Harness.SourceMapRecoder {
|
||||
}
|
||||
|
||||
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
|
||||
assert.isTrue(spansOnSingleLine.length == 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
|
||||
assert.isTrue(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
|
||||
recordSourceMapSpan(sourceMapSpan);
|
||||
|
||||
assert.isTrue(spansOnSingleLine.length === 1);
|
||||
@@ -395,9 +395,9 @@ module Harness.SourceMapRecoder {
|
||||
|
||||
var tsCodeLineMap = ts.computeLineStarts(sourceText);
|
||||
for (var i = 0; i < tsCodeLineMap.length; i++) {
|
||||
writeSourceMapIndent(prevEmittedCol, i == 0 ? markerIds[index] : " >");
|
||||
writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >");
|
||||
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
|
||||
if (i == tsCodeLineMap.length - 1) {
|
||||
if (i === tsCodeLineMap.length - 1) {
|
||||
sourceMapRecoder.WriteLine("");
|
||||
}
|
||||
}
|
||||
@@ -447,7 +447,7 @@ module Harness.SourceMapRecoder {
|
||||
for (var j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
||||
var decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
||||
var currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||
if (currentSourceFile != prevSourceFile) {
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
prevSourceFile = currentSourceFile;
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// Use this to get emitter-agnostic baselines
|
||||
|
||||
class SyntacticCleaner {
|
||||
static clean(sourceFileContents: string) {
|
||||
return sourceFileContents;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Re-implement or maybe delete
|
||||
class SyntacticCleaner extends TypeScript.SyntaxWalker {
|
||||
private emit: string[] = [];
|
||||
|
||||
public visitToken(token: TypeScript.ISyntaxToken): void {
|
||||
this.emit.push(token.text());
|
||||
if (token.kind() === TypeScript.SyntaxKind.SemicolonToken) {
|
||||
this.emit.push('\r\n');
|
||||
} else {
|
||||
this.emit.push(' ');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static clean(sourceFileContents: string): string {
|
||||
var parsed = TypeScript.Parser.parse('_emitted.ts', TypeScript.SimpleText.fromString(sourceFileContents), TypeScript.LanguageVersion.EcmaScript5, false);
|
||||
var cleaner = new SyntacticCleaner();
|
||||
cleaner.visitSourceUnit(parsed.sourceUnit());
|
||||
return cleaner.emit.join('');
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='runnerbase.ts' />
|
||||
/// <reference path='syntacticCleaner.ts' />
|
||||
|
||||
class Test262BaselineRunner extends RunnerBase {
|
||||
private static basePath = 'internal/cases/test262';
|
||||
@@ -65,7 +64,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
it('has the expected emitted code', () => {
|
||||
Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => {
|
||||
var files = testState.compilerResult.files.filter(f=> f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||
return Harness.Compiler.collateOutputs(files, s => SyntacticCleaner.clean(s));
|
||||
return Harness.Compiler.collateOutputs(files);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
|
||||
@@ -41,7 +41,10 @@ class TypeWriterWalker {
|
||||
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
|
||||
|
||||
var type = this.checker.getTypeAtLocation(node);
|
||||
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
|
||||
// var type = this.checker.getTypeAtLocation(node);
|
||||
var type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
|
||||
|
||||
ts.Debug.assert(type !== undefined, "type doesn't exist");
|
||||
var symbol = this.checker.getSymbolAtLocation(node);
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1150,7 +1150,7 @@ interface ArrayConstructor {
|
||||
(arrayLength?: number): any[];
|
||||
<T>(arrayLength: number): T[];
|
||||
<T>(...items: T[]): T[];
|
||||
isArray(arg: any): boolean;
|
||||
isArray(arg: any): arg is Array<any>;
|
||||
prototype: Array<any>;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
interface DOMTokenList {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
}
|
||||
|
||||
interface NodeList {
|
||||
[Symbol.iterator](): IterableIterator<Node>
|
||||
}
|
||||
|
||||
interface NodeListOf<TNode extends Node> {
|
||||
[Symbol.iterator](): IterableIterator<TNode>
|
||||
}
|
||||
Vendored
+14
-7
@@ -7677,10 +7677,10 @@ declare var MediaQueryList: {
|
||||
interface MediaSource extends EventTarget {
|
||||
activeSourceBuffers: SourceBufferList;
|
||||
duration: number;
|
||||
readyState: string;
|
||||
readyState: number;
|
||||
sourceBuffers: SourceBufferList;
|
||||
addSourceBuffer(type: string): SourceBuffer;
|
||||
endOfStream(error?: string): void;
|
||||
endOfStream(error?: number): void;
|
||||
removeSourceBuffer(sourceBuffer: SourceBuffer): void;
|
||||
}
|
||||
|
||||
@@ -8409,7 +8409,7 @@ declare var PopStateEvent: {
|
||||
|
||||
interface Position {
|
||||
coords: Coordinates;
|
||||
timestamp: Date;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
declare var Position: {
|
||||
@@ -11090,9 +11090,17 @@ interface WebGLRenderingContext {
|
||||
stencilMaskSeparate(face: number, mask: number): void;
|
||||
stencilOp(fail: number, zfail: number, zpass: number): void;
|
||||
stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
|
||||
texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView): void;
|
||||
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, image: HTMLImageElement): void;
|
||||
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, canvas: HTMLCanvasElement): void;
|
||||
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, video: HTMLVideoElement): void;
|
||||
texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageData): void;
|
||||
texParameterf(target: number, pname: number, param: number): void;
|
||||
texParameteri(target: number, pname: number, param: number): void;
|
||||
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView): void;
|
||||
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, image: HTMLImageElement): void;
|
||||
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, canvas: HTMLCanvasElement): void;
|
||||
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, video: HTMLVideoElement): void;
|
||||
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageData): void;
|
||||
uniform1f(location: WebGLUniformLocation, x: number): void;
|
||||
uniform1fv(location: WebGLUniformLocation, v: any): void;
|
||||
@@ -12332,10 +12340,11 @@ interface DocumentEvent {
|
||||
createEvent(eventInterface:"AriaRequestEvent"): AriaRequestEvent;
|
||||
createEvent(eventInterface:"AudioProcessingEvent"): AudioProcessingEvent;
|
||||
createEvent(eventInterface:"BeforeUnloadEvent"): BeforeUnloadEvent;
|
||||
createEvent(eventInterface:"ClipboardEvent"): ClipboardEvent;
|
||||
createEvent(eventInterface:"CloseEvent"): CloseEvent;
|
||||
createEvent(eventInterface:"CommandEvent"): CommandEvent;
|
||||
createEvent(eventInterface:"CompositionEvent"): CompositionEvent;
|
||||
createEvent(eventInterface: "CustomEvent"): CustomEvent;
|
||||
createEvent(eventInterface:"CustomEvent"): CustomEvent;
|
||||
createEvent(eventInterface:"DeviceMotionEvent"): DeviceMotionEvent;
|
||||
createEvent(eventInterface:"DeviceOrientationEvent"): DeviceOrientationEvent;
|
||||
createEvent(eventInterface:"DragEvent"): DragEvent;
|
||||
@@ -12358,8 +12367,6 @@ interface DocumentEvent {
|
||||
createEvent(eventInterface:"MouseEvent"): MouseEvent;
|
||||
createEvent(eventInterface:"MouseEvents"): MouseEvent;
|
||||
createEvent(eventInterface:"MouseWheelEvent"): MouseWheelEvent;
|
||||
createEvent(eventInterface:"MSGestureEvent"): MSGestureEvent;
|
||||
createEvent(eventInterface:"MSPointerEvent"): MSPointerEvent;
|
||||
createEvent(eventInterface:"MutationEvent"): MutationEvent;
|
||||
createEvent(eventInterface:"MutationEvents"): MutationEvent;
|
||||
createEvent(eventInterface:"NavigationCompletedEvent"): NavigationCompletedEvent;
|
||||
@@ -12971,4 +12978,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any,
|
||||
declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
|
||||
Vendored
+6
-1
@@ -41,6 +41,11 @@ declare module Intl {
|
||||
currency?: string;
|
||||
currencyDisplay?: string;
|
||||
useGrouping?: boolean;
|
||||
minimumintegerDigits?: number;
|
||||
minimumFractionDigits?: number;
|
||||
maximumFractionDigits?: number;
|
||||
minimumSignificantDigits?: number;
|
||||
maximumSignificantDigits?: number;
|
||||
}
|
||||
|
||||
interface ResolvedNumberFormatOptions {
|
||||
@@ -103,7 +108,7 @@ declare module Intl {
|
||||
}
|
||||
|
||||
interface DateTimeFormat {
|
||||
format(date: number): string;
|
||||
format(date?: Date | number): string;
|
||||
resolvedOptions(): ResolvedDateTimeFormatOptions;
|
||||
}
|
||||
var DateTimeFormat: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
module ts.server {
|
||||
namespace ts.server {
|
||||
|
||||
export interface SessionClientHost extends LanguageServiceHost {
|
||||
writeMessage(message: string): void;
|
||||
@@ -219,7 +219,7 @@ module ts.server {
|
||||
|
||||
var request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
|
||||
var response = this.processResponse<protocol.CompletionDetailsResponse>(request);
|
||||
Debug.assert(response.body.length == 1, "Unexpected length of completion details response body.");
|
||||
Debug.assert(response.body.length === 1, "Unexpected length of completion details response body.");
|
||||
return response.body[0];
|
||||
}
|
||||
|
||||
@@ -429,8 +429,8 @@ module ts.server {
|
||||
if (!this.lastRenameEntry ||
|
||||
this.lastRenameEntry.fileName !== fileName ||
|
||||
this.lastRenameEntry.position !== position ||
|
||||
this.lastRenameEntry.findInStrings != findInStrings ||
|
||||
this.lastRenameEntry.findInComments != findInComments) {
|
||||
this.lastRenameEntry.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.findInComments !== findInComments) {
|
||||
this.getRenameInfo(fileName, position, findInStrings, findInComments);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
/// <reference path="node.d.ts" />
|
||||
|
||||
module ts.server {
|
||||
namespace ts.server {
|
||||
export interface Logger {
|
||||
close(): void;
|
||||
isVerbose(): boolean;
|
||||
@@ -28,7 +27,7 @@ module ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
class ScriptInfo {
|
||||
export class ScriptInfo {
|
||||
svc: ScriptVersionCache;
|
||||
children: ScriptInfo[] = []; // files referenced by this file
|
||||
defaultProject: Project; // project to use by default for file
|
||||
@@ -36,7 +35,7 @@ module ts.server {
|
||||
formatCodeOptions = ts.clone(CompilerService.defaultFormatCodeOptions);
|
||||
|
||||
constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) {
|
||||
this.svc = ScriptVersionCache.fromString(content);
|
||||
this.svc = ScriptVersionCache.fromString(host, content);
|
||||
}
|
||||
|
||||
setFormatOptions(formatOptions: protocol.FormatOptions): void {
|
||||
@@ -80,7 +79,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
class LSHost implements ts.LanguageServiceHost {
|
||||
export class LSHost implements ts.LanguageServiceHost {
|
||||
ls: ts.LanguageService = null;
|
||||
compilationSettings: ts.CompilerOptions;
|
||||
filenameToScript: ts.Map<ScriptInfo> = {};
|
||||
@@ -273,7 +272,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
interface ProjectOptions {
|
||||
export interface ProjectOptions {
|
||||
// these fields can be present in the project file
|
||||
files?: string[];
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
@@ -376,7 +375,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
interface ProjectOpenResult {
|
||||
export interface ProjectOpenResult {
|
||||
success?: boolean;
|
||||
errorMsg?: string;
|
||||
project?: Project;
|
||||
@@ -392,11 +391,11 @@ module ts.server {
|
||||
return copiedList;
|
||||
}
|
||||
|
||||
interface ProjectServiceEventHandler {
|
||||
export interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
}
|
||||
|
||||
interface HostConfiguration {
|
||||
export interface HostConfiguration {
|
||||
formatCodeOptions: ts.FormatCodeOptions;
|
||||
hostInfo: string;
|
||||
}
|
||||
@@ -629,7 +628,7 @@ module ts.server {
|
||||
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
|
||||
var f = this.openFilesReferenced[i];
|
||||
// if f was referenced by the removed project, remember it
|
||||
if (f.defaultProject == removedProject) {
|
||||
if (f.defaultProject === removedProject) {
|
||||
f.defaultProject = undefined;
|
||||
orphanFiles.push(f);
|
||||
}
|
||||
@@ -656,7 +655,7 @@ module ts.server {
|
||||
for (var i = 0, len = this.inferredProjects.length; i < len; i++) {
|
||||
var inferredProject = this.inferredProjects[i];
|
||||
inferredProject.updateGraph();
|
||||
if (inferredProject != excludedProject) {
|
||||
if (inferredProject !== excludedProject) {
|
||||
if (inferredProject.getSourceFile(info)) {
|
||||
info.defaultProject = inferredProject;
|
||||
referencingProjects.push(inferredProject);
|
||||
@@ -710,7 +709,7 @@ module ts.server {
|
||||
var rootFile = this.openFileRoots[i];
|
||||
var rootedProject = rootFile.defaultProject;
|
||||
var referencingProjects = this.findReferencingProjects(rootFile, rootedProject);
|
||||
if (referencingProjects.length == 0) {
|
||||
if (referencingProjects.length === 0) {
|
||||
rootFile.defaultProject = rootedProject;
|
||||
openFileRoots.push(rootFile);
|
||||
}
|
||||
@@ -916,7 +915,7 @@ module ts.server {
|
||||
return rawConfig.error;
|
||||
}
|
||||
else {
|
||||
var parsedCommandLine = ts.parseConfigFile(rawConfig.config, ts.sys, dirPath);
|
||||
var parsedCommandLine = ts.parseConfigFile(rawConfig.config, this.host, dirPath);
|
||||
if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) {
|
||||
return { errorMsg: "tsconfig option errors" };
|
||||
}
|
||||
@@ -953,7 +952,7 @@ module ts.server {
|
||||
|
||||
}
|
||||
|
||||
class CompilerService {
|
||||
export class CompilerService {
|
||||
host: LSHost;
|
||||
languageService: ts.LanguageService;
|
||||
classifier: ts.Classifier;
|
||||
@@ -985,7 +984,7 @@ module ts.server {
|
||||
static defaultFormatCodeOptions: ts.FormatCodeOptions = {
|
||||
IndentSize: 4,
|
||||
TabSize: 4,
|
||||
NewLineCharacter: ts.sys.newLine,
|
||||
NewLineCharacter: ts.sys ? ts.sys.newLine : '\n',
|
||||
ConvertTabsToSpaces: true,
|
||||
InsertSpaceAfterCommaDelimiter: true,
|
||||
InsertSpaceAfterSemicolonInForStatements: true,
|
||||
@@ -999,7 +998,7 @@ module ts.server {
|
||||
|
||||
}
|
||||
|
||||
interface LineCollection {
|
||||
export interface LineCollection {
|
||||
charCount(): number;
|
||||
lineCount(): number;
|
||||
isLeaf(): boolean;
|
||||
@@ -1013,7 +1012,7 @@ module ts.server {
|
||||
leaf?: LineLeaf;
|
||||
}
|
||||
|
||||
enum CharRangeSection {
|
||||
export enum CharRangeSection {
|
||||
PreStart,
|
||||
Start,
|
||||
Entire,
|
||||
@@ -1022,7 +1021,7 @@ module ts.server {
|
||||
PostEnd
|
||||
}
|
||||
|
||||
interface ILineIndexWalker {
|
||||
export interface ILineIndexWalker {
|
||||
goSubtree: boolean;
|
||||
done: boolean;
|
||||
leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void;
|
||||
@@ -1082,7 +1081,7 @@ module ts.server {
|
||||
|
||||
for (var k = this.endBranch.length - 1; k >= 0; k--) {
|
||||
(<LineNode>this.endBranch[k]).updateCounts();
|
||||
if (this.endBranch[k].charCount() == 0) {
|
||||
if (this.endBranch[k].charCount() === 0) {
|
||||
lastZeroCount = this.endBranch[k];
|
||||
if (k > 0) {
|
||||
branchParent = <LineNode>this.endBranch[k - 1];
|
||||
@@ -1147,7 +1146,7 @@ module ts.server {
|
||||
post(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineCollection, nodeType: CharRangeSection): LineCollection {
|
||||
// have visited the path for start of range, now looking for end
|
||||
// if range is on single line, we will never make this state transition
|
||||
if (lineCollection == this.lineCollectionAtBranch) {
|
||||
if (lineCollection === this.lineCollectionAtBranch) {
|
||||
this.state = CharRangeSection.End;
|
||||
}
|
||||
// always pop stack because post only called when child has been visited
|
||||
@@ -1159,7 +1158,7 @@ module ts.server {
|
||||
// currentNode corresponds to parent, but in the new tree
|
||||
var currentNode = this.stack[this.stack.length - 1];
|
||||
|
||||
if ((this.state == CharRangeSection.Entire) && (nodeType == CharRangeSection.Start)) {
|
||||
if ((this.state === CharRangeSection.Entire) && (nodeType === CharRangeSection.Start)) {
|
||||
// if range is on single line, we will never make this state transition
|
||||
this.state = CharRangeSection.Start;
|
||||
this.branchNode = currentNode;
|
||||
@@ -1176,12 +1175,12 @@ module ts.server {
|
||||
switch (nodeType) {
|
||||
case CharRangeSection.PreStart:
|
||||
this.goSubtree = false;
|
||||
if (this.state != CharRangeSection.End) {
|
||||
if (this.state !== CharRangeSection.End) {
|
||||
currentNode.add(lineCollection);
|
||||
}
|
||||
break;
|
||||
case CharRangeSection.Start:
|
||||
if (this.state == CharRangeSection.End) {
|
||||
if (this.state === CharRangeSection.End) {
|
||||
this.goSubtree = false;
|
||||
}
|
||||
else {
|
||||
@@ -1191,7 +1190,7 @@ module ts.server {
|
||||
}
|
||||
break;
|
||||
case CharRangeSection.Entire:
|
||||
if (this.state != CharRangeSection.End) {
|
||||
if (this.state !== CharRangeSection.End) {
|
||||
child = fresh(lineCollection);
|
||||
currentNode.add(child);
|
||||
this.startPath[this.startPath.length] = child;
|
||||
@@ -1208,7 +1207,7 @@ module ts.server {
|
||||
this.goSubtree = false;
|
||||
break;
|
||||
case CharRangeSection.End:
|
||||
if (this.state != CharRangeSection.End) {
|
||||
if (this.state !== CharRangeSection.End) {
|
||||
this.goSubtree = false;
|
||||
}
|
||||
else {
|
||||
@@ -1221,7 +1220,7 @@ module ts.server {
|
||||
break;
|
||||
case CharRangeSection.PostEnd:
|
||||
this.goSubtree = false;
|
||||
if (this.state != CharRangeSection.Start) {
|
||||
if (this.state !== CharRangeSection.Start) {
|
||||
currentNode.add(lineCollection);
|
||||
}
|
||||
break;
|
||||
@@ -1233,10 +1232,10 @@ module ts.server {
|
||||
}
|
||||
// just gather text from the leaves
|
||||
leaf(relativeStart: number, relativeLength: number, ll: LineLeaf) {
|
||||
if (this.state == CharRangeSection.Start) {
|
||||
if (this.state === CharRangeSection.Start) {
|
||||
this.initialText = ll.text.substring(0, relativeStart);
|
||||
}
|
||||
else if (this.state == CharRangeSection.Entire) {
|
||||
else if (this.state === CharRangeSection.Entire) {
|
||||
this.initialText = ll.text.substring(0, relativeStart);
|
||||
this.trailingText = ll.text.substring(relativeStart + relativeLength);
|
||||
}
|
||||
@@ -1248,7 +1247,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
// text change information
|
||||
class TextChange {
|
||||
export class TextChange {
|
||||
constructor(public pos: number, public deleteLen: number, public insertedText?: string) {
|
||||
}
|
||||
|
||||
@@ -1263,6 +1262,7 @@ module ts.server {
|
||||
versions: LineIndexSnapshot[] = [];
|
||||
minVersion = 0; // no versions earlier than min version will maintain change history
|
||||
private currentVersion = 0;
|
||||
private host: ServerHost;
|
||||
|
||||
static changeNumberThreshold = 8;
|
||||
static changeLengthThreshold = 256;
|
||||
@@ -1290,7 +1290,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
reloadFromFile(filename: string, cb?: () => any) {
|
||||
var content = ts.sys.readFile(filename);
|
||||
var content = this.host.readFile(filename);
|
||||
this.reload(content);
|
||||
if (cb)
|
||||
cb();
|
||||
@@ -1360,10 +1360,11 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
static fromString(script: string) {
|
||||
static fromString(host: ServerHost, script: string) {
|
||||
var svc = new ScriptVersionCache();
|
||||
var snap = new LineIndexSnapshot(0, svc);
|
||||
svc.versions[svc.currentVersion] = snap;
|
||||
svc.host = host;
|
||||
snap.index = new LineIndex();
|
||||
var lm = LineIndex.linesFromText(script);
|
||||
snap.index.load(lm.lines);
|
||||
@@ -1371,7 +1372,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
class LineIndexSnapshot implements ts.IScriptSnapshot {
|
||||
export class LineIndexSnapshot implements ts.IScriptSnapshot {
|
||||
index: LineIndex;
|
||||
changesSincePreviousVersion: TextChange[] = [];
|
||||
|
||||
@@ -1499,8 +1500,8 @@ module ts.server {
|
||||
function editFlat(source: string, s: number, dl: number, nt = "") {
|
||||
return source.substring(0, s) + nt + source.substring(s + dl, source.length);
|
||||
}
|
||||
if (this.root.charCount() == 0) {
|
||||
// TODO: assert deleteLength == 0
|
||||
if (this.root.charCount() === 0) {
|
||||
// TODO: assert deleteLength === 0
|
||||
if (newText) {
|
||||
this.load(LineIndex.linesFromText(newText).lines);
|
||||
return this;
|
||||
@@ -1528,7 +1529,7 @@ module ts.server {
|
||||
// check whether last characters deleted are line break
|
||||
var e = pos + deleteLength;
|
||||
var lineInfo = this.charOffsetToLineNumberAndPos(e);
|
||||
if ((lineInfo && (lineInfo.offset == 0))) {
|
||||
if ((lineInfo && (lineInfo.offset === 0))) {
|
||||
// move range end just past line that will merge with previous line
|
||||
deleteLength += lineInfo.text.length;
|
||||
// store text by appending to end of insertedText
|
||||
@@ -1574,7 +1575,7 @@ module ts.server {
|
||||
interiorNodes[i].totalChars = charCount;
|
||||
interiorNodes[i].totalLines = lineCount;
|
||||
}
|
||||
if (interiorNodes.length == 1) {
|
||||
if (interiorNodes.length === 1) {
|
||||
return interiorNodes[0];
|
||||
}
|
||||
else {
|
||||
@@ -1585,7 +1586,7 @@ module ts.server {
|
||||
static linesFromText(text: string) {
|
||||
var lineStarts = ts.computeLineStarts(text);
|
||||
|
||||
if (lineStarts.length == 0) {
|
||||
if (lineStarts.length === 0) {
|
||||
return { lines: <string[]>[], lineMap: lineStarts };
|
||||
}
|
||||
var lines = <string[]>new Array(lineStarts.length);
|
||||
@@ -1605,7 +1606,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
class LineNode implements LineCollection {
|
||||
export class LineNode implements LineCollection {
|
||||
totalChars = 0;
|
||||
totalLines = 0;
|
||||
children: LineCollection[] = [];
|
||||
@@ -1821,7 +1822,7 @@ module ts.server {
|
||||
findChildIndex(child: LineCollection) {
|
||||
var childIndex = 0;
|
||||
var clen = this.children.length;
|
||||
while ((this.children[childIndex] != child) && (childIndex < clen)) childIndex++;
|
||||
while ((this.children[childIndex] !== child) && (childIndex < clen)) childIndex++;
|
||||
return childIndex;
|
||||
}
|
||||
|
||||
@@ -1830,7 +1831,7 @@ module ts.server {
|
||||
var clen = this.children.length;
|
||||
var nodeCount = nodes.length;
|
||||
// if child is last and there is more room and only one node to place, place it
|
||||
if ((clen < lineCollectionCapacity) && (childIndex == (clen - 1)) && (nodeCount == 1)) {
|
||||
if ((clen < lineCollectionCapacity) && (childIndex === (clen - 1)) && (nodeCount === 1)) {
|
||||
this.add(nodes[0]);
|
||||
this.updateCounts();
|
||||
return [];
|
||||
@@ -1854,13 +1855,13 @@ module ts.server {
|
||||
var splitNode = <LineNode>splitNodes[0];
|
||||
while (nodeIndex < nodeCount) {
|
||||
splitNode.add(nodes[nodeIndex++]);
|
||||
if (splitNode.children.length == lineCollectionCapacity) {
|
||||
if (splitNode.children.length === lineCollectionCapacity) {
|
||||
splitNodeIndex++;
|
||||
splitNode = <LineNode>splitNodes[splitNodeIndex];
|
||||
}
|
||||
}
|
||||
for (i = splitNodes.length - 1; i >= 0; i--) {
|
||||
if (splitNodes[i].children.length == 0) {
|
||||
if (splitNodes[i].children.length === 0) {
|
||||
splitNodes.length--;
|
||||
}
|
||||
}
|
||||
@@ -1891,7 +1892,7 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
class LineLeaf implements LineCollection {
|
||||
export class LineLeaf implements LineCollection {
|
||||
udata: any;
|
||||
|
||||
constructor(public text: string) {
|
||||
|
||||
Vendored
+2
-2
@@ -584,9 +584,9 @@ declare module NodeJS {
|
||||
export interface Response extends Message {
|
||||
request_seq: number;
|
||||
success: boolean;
|
||||
/** Contains error message if success == false. */
|
||||
/** Contains error message if success === false. */
|
||||
message?: string;
|
||||
/** Contains message body if success == true. */
|
||||
/** Contains message body if success === true. */
|
||||
body?: any;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Declaration module describing the TypeScript Server protocol
|
||||
*/
|
||||
declare module ts.server.protocol {
|
||||
declare namespace ts.server.protocol {
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
*/
|
||||
@@ -67,12 +67,12 @@ declare module ts.server.protocol {
|
||||
command: string;
|
||||
|
||||
/**
|
||||
* Contains error message if success == false.
|
||||
* Contains error message if success === false.
|
||||
*/
|
||||
message?: string;
|
||||
|
||||
/**
|
||||
* Contains message body if success == true.
|
||||
* Contains message body if success === true.
|
||||
*/
|
||||
body?: any;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="node.d.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
module ts.server {
|
||||
namespace ts.server {
|
||||
var nodeproto: typeof NodeJS._debugger = require('_debugger');
|
||||
var readline: NodeJS.ReadLine = require('readline');
|
||||
var path: NodeJS.Path = require('path');
|
||||
@@ -11,7 +11,7 @@ module ts.server {
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
terminal: false,
|
||||
});
|
||||
});
|
||||
|
||||
class Logger implements ts.server.Logger {
|
||||
fd = -1;
|
||||
@@ -123,7 +123,7 @@ module ts.server {
|
||||
if (err) {
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
else if (watchedFile.mtime.getTime() != stats.mtime.getTime()) {
|
||||
else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
|
||||
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
|
||||
watchedFile.callback(watchedFile.fileName);
|
||||
}
|
||||
@@ -138,7 +138,7 @@ module ts.server {
|
||||
var count = 0;
|
||||
var nextToCheck = this.nextFileToCheck;
|
||||
var firstCheck = -1;
|
||||
while ((count < this.chunkSize) && (nextToCheck != firstCheck)) {
|
||||
while ((count < this.chunkSize) && (nextToCheck !== firstCheck)) {
|
||||
this.poll(nextToCheck);
|
||||
if (firstCheck < 0) {
|
||||
firstCheck = nextToCheck;
|
||||
@@ -170,11 +170,11 @@ module ts.server {
|
||||
removeFile(file: WatchedFile) {
|
||||
this.watchedFiles = WatchedFileSet.copyListRemovingItem(file, this.watchedFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
constructor(host: ServerHost, logger: ts.server.Logger) {
|
||||
super(host, logger);
|
||||
super(host, Buffer.byteLength, process.hrtime, logger);
|
||||
}
|
||||
|
||||
exit() {
|
||||
|
||||
+21
-17
@@ -1,10 +1,9 @@
|
||||
/// <reference path="..\compiler\commandLineParser.ts" />
|
||||
/// <reference path="..\services\services.ts" />
|
||||
/// <reference path="node.d.ts" />
|
||||
/// <reference path="protocol.d.ts" />
|
||||
/// <reference path="editorServices.ts" />
|
||||
|
||||
module ts.server {
|
||||
namespace ts.server {
|
||||
var spaceCache:string[] = [];
|
||||
|
||||
interface StackTraceError extends Error {
|
||||
@@ -31,7 +30,7 @@ module ts.server {
|
||||
if (a < b) {
|
||||
return -1;
|
||||
}
|
||||
else if (a == b) {
|
||||
else if (a === b) {
|
||||
return 0;
|
||||
}
|
||||
else return 1;
|
||||
@@ -43,7 +42,7 @@ module ts.server {
|
||||
}
|
||||
else if (a.file == b.file) {
|
||||
var n = compareNumber(a.start.line, b.start.line);
|
||||
if (n == 0) {
|
||||
if (n === 0) {
|
||||
return compareNumber(a.start.offset, b.start.offset);
|
||||
}
|
||||
else return n;
|
||||
@@ -61,7 +60,7 @@ module ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
interface PendingErrorCheck {
|
||||
export interface PendingErrorCheck {
|
||||
fileName: string;
|
||||
project: Project;
|
||||
}
|
||||
@@ -114,11 +113,16 @@ module ts.server {
|
||||
pendingOperation = false;
|
||||
fileHash: ts.Map<number> = {};
|
||||
nextFileId = 1;
|
||||
errorTimer: NodeJS.Timer;
|
||||
errorTimer: any; /*NodeJS.Timer | number*/
|
||||
immediateId: any;
|
||||
changeSeq = 0;
|
||||
|
||||
constructor(private host: ServerHost, private logger: Logger) {
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
private byteLength: (buf: string, encoding?: string) => number,
|
||||
private hrtime: (start?: number[]) => number[],
|
||||
private logger: Logger
|
||||
) {
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName,project,fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
@@ -129,7 +133,7 @@ module ts.server {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n == this.changeSeq, 100);
|
||||
(n) => n === this.changeSeq, 100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,17 +153,17 @@ module ts.server {
|
||||
this.host.write(line + this.host.newLine);
|
||||
}
|
||||
|
||||
send(msg: NodeJS._debugger.Message) {
|
||||
send(msg: protocol.Message) {
|
||||
var json = JSON.stringify(msg);
|
||||
if (this.logger.isVerbose()) {
|
||||
this.logger.info(msg.type + ": " + json);
|
||||
}
|
||||
this.sendLineToClient('Content-Length: ' + (1 + Buffer.byteLength(json, 'utf8')) +
|
||||
this.sendLineToClient('Content-Length: ' + (1 + this.byteLength(json, 'utf8')) +
|
||||
'\r\n\r\n' + json);
|
||||
}
|
||||
|
||||
event(info: any, eventName: string) {
|
||||
var ev: NodeJS._debugger.Event = {
|
||||
var ev: protocol.Event = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
@@ -546,7 +550,7 @@ module ts.server {
|
||||
// getFormattingEditsAfterKeytroke either empty or pertaining
|
||||
// only to the previous line. If all this is true, then
|
||||
// add edits necessary to properly indent the current line.
|
||||
if ((key == "\n") && ((!edits) || (edits.length == 0) || allEditsBeforePos(edits, position))) {
|
||||
if ((key == "\n") && ((!edits) || (edits.length === 0) || allEditsBeforePos(edits, position))) {
|
||||
var scriptInfo = compilerService.host.getScriptInfo(file);
|
||||
if (scriptInfo) {
|
||||
var lineInfo = scriptInfo.getLineInfo(line);
|
||||
@@ -622,7 +626,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
return completions.entries.reduce((result: protocol.CompletionEntry[], entry: ts.CompletionEntry) => {
|
||||
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) == 0)) {
|
||||
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
|
||||
result.push(entry);
|
||||
}
|
||||
return result;
|
||||
@@ -689,7 +693,7 @@ module ts.server {
|
||||
}, []);
|
||||
|
||||
if (checkList.length > 0) {
|
||||
this.updateErrorCheck(checkList, this.changeSeq,(n) => n == this.changeSeq, delay)
|
||||
this.updateErrorCheck(checkList, this.changeSeq,(n) => n === this.changeSeq, delay)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,7 +708,7 @@ module ts.server {
|
||||
compilerService.host.editScript(file, start, end, insertString);
|
||||
this.changeSeq++;
|
||||
}
|
||||
this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
|
||||
this.updateProjectStructure(this.changeSeq, (n) => n === this.changeSeq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,7 +842,7 @@ module ts.server {
|
||||
onMessage(message: string) {
|
||||
if (this.logger.isVerbose()) {
|
||||
this.logger.info("request: " + message);
|
||||
var start = process.hrtime();
|
||||
var start = this.hrtime();
|
||||
}
|
||||
try {
|
||||
var request = <protocol.Request>JSON.parse(message);
|
||||
@@ -980,7 +984,7 @@ module ts.server {
|
||||
}
|
||||
|
||||
if (this.logger.isVerbose()) {
|
||||
var elapsed = process.hrtime(start);
|
||||
var elapsed = this.hrtime(start);
|
||||
var seconds = elapsed[0]
|
||||
var nanoseconds = elapsed[1];
|
||||
var elapsedMs = ((1e9 * seconds) + nanoseconds)/1000000.0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/// <reference path='services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.BreakpointResolver {
|
||||
namespace ts.BreakpointResolver {
|
||||
/**
|
||||
* Get the breakpoint span in given sourceFile
|
||||
*/
|
||||
@@ -75,7 +75,7 @@ module ts.BreakpointResolver {
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
if (node.parent.kind == SyntaxKind.ArrowFunction && (<FunctionLikeDeclaration>node.parent).body == node) {
|
||||
if (node.parent.kind === SyntaxKind.ArrowFunction && (<FunctionLikeDeclaration>node.parent).body === node) {
|
||||
// If this is body of arrow function, it is allowed to have the breakpoint
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
|
||||
export interface TextRangeWithKind extends TextRange {
|
||||
kind: SyntaxKind;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class FormattingContext {
|
||||
public currentTokenSpan: TextRangeWithKind;
|
||||
public nextTokenSpan: TextRangeWithKind;
|
||||
@@ -59,7 +59,7 @@ module ts.formatting {
|
||||
if (this.tokensAreOnSameLine === undefined) {
|
||||
let startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
|
||||
let endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
|
||||
this.tokensAreOnSameLine = (startLine == endLine);
|
||||
this.tokensAreOnSameLine = (startLine === endLine);
|
||||
}
|
||||
|
||||
return this.tokensAreOnSameLine;
|
||||
@@ -84,7 +84,7 @@ module ts.formatting {
|
||||
private NodeIsOnOneLine(node: Node): boolean {
|
||||
let startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
|
||||
let endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
|
||||
return startLine == endLine;
|
||||
return startLine === endLine;
|
||||
}
|
||||
|
||||
private BlockIsOnOneLine(node: Node): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum FormattingRequestKind {
|
||||
FormatDocument,
|
||||
FormatSelection,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/// <reference path="..\..\compiler\scanner.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
|
||||
|
||||
export interface FormattingScanner {
|
||||
@@ -224,7 +224,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
function isOnToken(): boolean {
|
||||
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
|
||||
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
|
||||
let startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
|
||||
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class Rule {
|
||||
constructor(
|
||||
public Descriptor: RuleDescriptor,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum RuleAction {
|
||||
Ignore = 0x00000001,
|
||||
Space = 0x00000002,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RuleDescriptor {
|
||||
constructor(public LeftTokenRange: Shared.TokenRange, public RightTokenRange: Shared.TokenRange) {
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum RuleFlags {
|
||||
None,
|
||||
CanDeleteNewLines
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RuleOperation {
|
||||
public Context: RuleOperationContext;
|
||||
public Action: RuleAction;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
|
||||
export class RuleOperationContext {
|
||||
private customContextChecks: { (context: FormattingContext): boolean; }[];
|
||||
@@ -14,7 +14,7 @@ module ts.formatting {
|
||||
|
||||
|
||||
public IsAny(): boolean {
|
||||
return this == RuleOperationContext.Any;
|
||||
return this === RuleOperationContext.Any;
|
||||
}
|
||||
|
||||
public InContext(context: FormattingContext): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class Rules {
|
||||
public getRuleName(rule: Rule) {
|
||||
let o: ts.Map<any> = <any>this;
|
||||
@@ -193,7 +193,7 @@ module ts.formatting {
|
||||
// Insert space after function keyword for anonymous functions
|
||||
public SpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
public NoSpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
|
||||
|
||||
// Insert space after @ in decorator
|
||||
public SpaceBeforeAt: Rule;
|
||||
public NoSpaceAfterAt: Rule;
|
||||
@@ -470,8 +470,9 @@ module ts.formatting {
|
||||
switch (context.contextNode.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.TypePredicate:
|
||||
return true;
|
||||
|
||||
|
||||
// equals in binding elements: function foo([[x, y] = [1, 2]])
|
||||
case SyntaxKind.BindingElement:
|
||||
// equals in type X = ...
|
||||
@@ -691,7 +692,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
static IsNotFormatOnEnter(context: FormattingContext): boolean {
|
||||
return context.formattingRequestKind != FormattingRequestKind.FormatOnEnter;
|
||||
return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter;
|
||||
}
|
||||
|
||||
static IsModuleDeclContext(context: FormattingContext): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RulesMap {
|
||||
public map: RulesBucket[];
|
||||
public mapRowLength: number;
|
||||
@@ -41,15 +41,15 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
|
||||
let specificRule = rule.Descriptor.LeftTokenRange != Shared.TokenRange.Any &&
|
||||
rule.Descriptor.RightTokenRange != Shared.TokenRange.Any;
|
||||
let specificRule = rule.Descriptor.LeftTokenRange !== Shared.TokenRange.Any &&
|
||||
rule.Descriptor.RightTokenRange !== Shared.TokenRange.Any;
|
||||
|
||||
rule.Descriptor.LeftTokenRange.GetTokens().forEach((left) => {
|
||||
rule.Descriptor.RightTokenRange.GetTokens().forEach((right) => {
|
||||
let rulesBucketIndex = this.GetRuleBucketIndex(left, right);
|
||||
|
||||
let rulesBucket = this.map[rulesBucketIndex];
|
||||
if (rulesBucket == undefined) {
|
||||
if (rulesBucket === undefined) {
|
||||
rulesBucket = this.map[rulesBucketIndex] = new RulesBucket();
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ module ts.formatting {
|
||||
public IncreaseInsertionIndex(maskPosition: RulesPosition): void {
|
||||
let value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask;
|
||||
value++;
|
||||
Debug.assert((value & Mask) == value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
|
||||
Debug.assert((value & Mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
|
||||
|
||||
let temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition);
|
||||
temp |= value << maskPosition;
|
||||
@@ -147,7 +147,7 @@ module ts.formatting {
|
||||
public AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void {
|
||||
let position: RulesPosition;
|
||||
|
||||
if (rule.Operation.Action == RuleAction.Ignore) {
|
||||
if (rule.Operation.Action === RuleAction.Ignore) {
|
||||
position = specificTokens ?
|
||||
RulesPosition.IgnoreRulesSpecific :
|
||||
RulesPosition.IgnoreRulesAny;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RulesProvider {
|
||||
private globalRules: Rules;
|
||||
private options: ts.FormatCodeOptions;
|
||||
@@ -25,6 +25,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
public ensureUpToDate(options: ts.FormatCodeOptions) {
|
||||
// TODO: Should this be '==='?
|
||||
if (this.options == null || !ts.compareDataObjects(this.options, options)) {
|
||||
let activeRules = this.createActiveRules(options);
|
||||
let rulesMap = RulesMap.create(activeRules);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='..\services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export module SmartIndenter {
|
||||
|
||||
const enum Value {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export module Shared {
|
||||
export interface ITokenAccess {
|
||||
GetTokens(): SyntaxKind[];
|
||||
@@ -54,7 +54,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
public Contains(tokenValue: SyntaxKind): boolean {
|
||||
return tokenValue == this.token;
|
||||
return tokenValue === this.token;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ module ts.formatting {
|
||||
static AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([SyntaxKind.MultiLineCommentTrivia]));
|
||||
static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
|
||||
static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword]);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.IsKeyword]);
|
||||
static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]);
|
||||
static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts.NavigateTo {
|
||||
namespace ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
|
||||
|
||||
export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[] {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path='services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.NavigationBar {
|
||||
namespace ts.NavigationBar {
|
||||
export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] {
|
||||
// If the source file has any child items, then it included in the tree
|
||||
// and takes lexical ownership of all other top-level items.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export module OutliningElementsCollector {
|
||||
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
|
||||
let elements: OutliningSpan[] = [];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
// Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
|
||||
export enum PatternMatchKind {
|
||||
exact,
|
||||
@@ -686,7 +686,7 @@ module ts {
|
||||
|
||||
if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
|
||||
charIsPunctuation(identifier.charCodeAt(i)) ||
|
||||
lastIsDigit != currentIsDigit ||
|
||||
lastIsDigit !== currentIsDigit ||
|
||||
hasTransitionFromLowerToUpper ||
|
||||
hasTransitionFromUpperToLower) {
|
||||
|
||||
@@ -757,7 +757,7 @@ module ts {
|
||||
// 3) HTMLDocument -> HTML, Document
|
||||
//
|
||||
// etc.
|
||||
if (index != wordStart &&
|
||||
if (index !== wordStart &&
|
||||
index + 1 < identifier.length) {
|
||||
let currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
|
||||
let nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1));
|
||||
|
||||
+125
-83
@@ -10,7 +10,7 @@
|
||||
/// <reference path='formatting\formatting.ts' />
|
||||
/// <reference path='formatting\smartIndenter.ts' />
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
/** The version of the language service API */
|
||||
export let servicesVersion = "0.4"
|
||||
|
||||
@@ -167,7 +167,7 @@ module ts {
|
||||
}
|
||||
|
||||
public getFullWidth(): number {
|
||||
return this.end - this.getFullStart();
|
||||
return this.end - this.pos;
|
||||
}
|
||||
|
||||
public getLeadingTriviaWidth(sourceFile?: SourceFile): number {
|
||||
@@ -735,7 +735,7 @@ module ts {
|
||||
public endOfFileToken: Node;
|
||||
|
||||
public amdDependencies: { name: string; path: string }[];
|
||||
public amdModuleName: string;
|
||||
public moduleName: string;
|
||||
public referencedFiles: FileReference[];
|
||||
|
||||
public syntacticDiagnostics: Diagnostic[];
|
||||
@@ -743,6 +743,7 @@ module ts {
|
||||
public parseDiagnostics: Diagnostic[];
|
||||
public bindDiagnostics: Diagnostic[];
|
||||
|
||||
public isDefaultLib: boolean;
|
||||
public hasNoDefaultLib: boolean;
|
||||
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
|
||||
public nodeCount: number;
|
||||
@@ -960,6 +961,7 @@ module ts {
|
||||
log? (s: string): void;
|
||||
trace? (s: string): void;
|
||||
error? (s: string): void;
|
||||
useCaseSensitiveFileNames? (): boolean;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -971,6 +973,9 @@ module ts {
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Diagnostic[];
|
||||
getSemanticDiagnostics(fileName: string): Diagnostic[];
|
||||
|
||||
// TODO: Rename this to getProgramDiagnostics to better indicate that these are any
|
||||
// diagnostics present for the program level, and not just 'options' diagnostics.
|
||||
getCompilerOptionsDiagnostics(): Diagnostic[];
|
||||
|
||||
/**
|
||||
@@ -1632,12 +1637,12 @@ module ts {
|
||||
// at each language service public entry point, since we don't know when
|
||||
// set of scripts handled by the host changes.
|
||||
class HostCache {
|
||||
private fileNameToEntry: Map<HostFileInformation>;
|
||||
private fileNameToEntry: FileMap<HostFileInformation>;
|
||||
private _compilationSettings: CompilerOptions;
|
||||
|
||||
constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) {
|
||||
constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) {
|
||||
// script id => script index
|
||||
this.fileNameToEntry = {};
|
||||
this.fileNameToEntry = createFileMap<HostFileInformation>(getCanonicalFileName);
|
||||
|
||||
// Initialize the list with the root file names
|
||||
let rootFileNames = host.getScriptFileNames();
|
||||
@@ -1653,10 +1658,6 @@ module ts {
|
||||
return this._compilationSettings;
|
||||
}
|
||||
|
||||
private normalizeFileName(fileName: string): string {
|
||||
return this.getCanonicalFileName(normalizeSlashes(fileName));
|
||||
}
|
||||
|
||||
private createEntry(fileName: string) {
|
||||
let entry: HostFileInformation;
|
||||
let scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
@@ -1668,15 +1669,16 @@ module ts {
|
||||
};
|
||||
}
|
||||
|
||||
return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry;
|
||||
this.fileNameToEntry.set(fileName, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private getEntry(fileName: string): HostFileInformation {
|
||||
return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName));
|
||||
return this.fileNameToEntry.get(fileName);
|
||||
}
|
||||
|
||||
private contains(fileName: string): boolean {
|
||||
return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName));
|
||||
return this.fileNameToEntry.contains(fileName);
|
||||
}
|
||||
|
||||
public getOrCreateEntry(fileName: string): HostFileInformation {
|
||||
@@ -1690,10 +1692,9 @@ module ts {
|
||||
public getRootFileNames(): string[] {
|
||||
let fileNames: string[] = [];
|
||||
|
||||
forEachKey(this.fileNameToEntry, key => {
|
||||
let entry = this.getEntry(key);
|
||||
if (entry) {
|
||||
fileNames.push(entry.hostFileName);
|
||||
this.fileNameToEntry.forEachValue(value => {
|
||||
if (value) {
|
||||
fileNames.push(value.hostFileName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1765,8 +1766,10 @@ module ts {
|
||||
* Extra compiler options that will unconditionally be used bu this function are:
|
||||
* - isolatedModules = true
|
||||
* - allowNonTsExtensions = true
|
||||
* - noLib = true
|
||||
* - noResolve = true
|
||||
*/
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string {
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
|
||||
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
|
||||
|
||||
options.isolatedModules = true;
|
||||
@@ -1774,15 +1777,23 @@ module ts {
|
||||
// Filename can be non-ts file.
|
||||
options.allowNonTsExtensions = true;
|
||||
|
||||
// Parse
|
||||
var inputFileName = fileName || "module.ts";
|
||||
var sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
// We are not returning a sourceFile for lib file when asked by the program,
|
||||
// so pass --noLib to avoid reporting a file not found error.
|
||||
options.noLib = true;
|
||||
|
||||
// Store syntactic diagnostics
|
||||
if (diagnostics && sourceFile.parseDiagnostics) {
|
||||
diagnostics.push(...sourceFile.parseDiagnostics);
|
||||
// We are not doing a full typecheck, we are not resolving the whole context,
|
||||
// so pass --noResolve to avoid reporting missing file errors.
|
||||
options.noResolve = true;
|
||||
|
||||
// Parse
|
||||
let inputFileName = fileName || "module.ts";
|
||||
let sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
if (moduleName) {
|
||||
sourceFile.moduleName = moduleName;
|
||||
}
|
||||
|
||||
let newLine = getNewLineCharacter(options);
|
||||
|
||||
// Output
|
||||
let outputText: string;
|
||||
|
||||
@@ -1797,14 +1808,13 @@ module ts {
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: () => "",
|
||||
getNewLine: () => (sys && sys.newLine) || "\r\n"
|
||||
getNewLine: () => newLine
|
||||
};
|
||||
|
||||
var program = createProgram([inputFileName], options, compilerHost);
|
||||
|
||||
if (diagnostics) {
|
||||
diagnostics.push(...program.getGlobalDiagnostics());
|
||||
}
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
|
||||
|
||||
// Emit
|
||||
program.emit();
|
||||
@@ -1873,20 +1883,28 @@ module ts {
|
||||
return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true);
|
||||
}
|
||||
|
||||
export function createDocumentRegistry(): DocumentRegistry {
|
||||
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitivefileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean): DocumentRegistry {
|
||||
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
|
||||
// for those settings.
|
||||
let buckets: Map<Map<DocumentRegistryEntry>> = {};
|
||||
let buckets: Map<FileMap<DocumentRegistryEntry>> = {};
|
||||
let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
|
||||
|
||||
function getKeyFromCompilationSettings(settings: CompilerOptions): string {
|
||||
return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString()
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): Map<DocumentRegistryEntry> {
|
||||
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
|
||||
let key = getKeyFromCompilationSettings(settings);
|
||||
let bucket = lookUp(buckets, key);
|
||||
if (!bucket && createIfMissing) {
|
||||
buckets[key] = bucket = {};
|
||||
buckets[key] = bucket = createFileMap<DocumentRegistryEntry>(getCanonicalFileName);
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
@@ -1896,7 +1914,7 @@ module ts {
|
||||
let entries = lookUp(buckets, name);
|
||||
let sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
|
||||
for (let i in entries) {
|
||||
let entry = entries[i];
|
||||
let entry = entries.get(i);
|
||||
sourceFiles.push({
|
||||
name: i,
|
||||
refCount: entry.languageServiceRefCount,
|
||||
@@ -1928,18 +1946,19 @@ module ts {
|
||||
acquiring: boolean): SourceFile {
|
||||
|
||||
let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true);
|
||||
let entry = lookUp(bucket, fileName);
|
||||
let entry = bucket.get(fileName);
|
||||
if (!entry) {
|
||||
Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
|
||||
|
||||
// Have never seen this file with these settings. Create a new source file for it.
|
||||
let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false);
|
||||
|
||||
bucket[fileName] = entry = {
|
||||
entry = {
|
||||
sourceFile: sourceFile,
|
||||
languageServiceRefCount: 0,
|
||||
owners: []
|
||||
};
|
||||
bucket.set(fileName, entry);
|
||||
}
|
||||
else {
|
||||
// We have an entry for this file. However, it may be for a different version of
|
||||
@@ -1967,12 +1986,12 @@ module ts {
|
||||
let bucket = getBucketForCompilationSettings(compilationSettings, false);
|
||||
Debug.assert(bucket !== undefined);
|
||||
|
||||
let entry = lookUp(bucket, fileName);
|
||||
let entry = bucket.get(fileName);
|
||||
entry.languageServiceRefCount--;
|
||||
|
||||
Debug.assert(entry.languageServiceRefCount >= 0);
|
||||
if (entry.languageServiceRefCount === 0) {
|
||||
delete bucket[fileName];
|
||||
bucket.remove(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2400,9 +2419,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getCanonicalFileName(fileName: string) {
|
||||
return useCaseSensitivefileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames);
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
@@ -2776,7 +2793,7 @@ module ts {
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getGlobalDiagnostics();
|
||||
return program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
}
|
||||
|
||||
/// Completion
|
||||
@@ -4168,7 +4185,7 @@ module ts {
|
||||
var result: DefinitionInfo[] = [];
|
||||
forEach((<UnionType>type).types, t => {
|
||||
if (t.symbol) {
|
||||
result.push(...getDefinitionFromSymbol(t.symbol, node));
|
||||
addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@@ -5756,7 +5773,8 @@ module ts {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.ExpressionWithTypeArguments;
|
||||
return node.parent.kind === SyntaxKind.TypeReference ||
|
||||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent));
|
||||
}
|
||||
|
||||
function isNamespaceReference(node: Node): boolean {
|
||||
@@ -5937,6 +5955,7 @@ module ts {
|
||||
let typeChecker = program.getTypeChecker();
|
||||
|
||||
let result: number[] = [];
|
||||
let classifiableNames = program.getClassifiableNames();
|
||||
processNode(sourceFile);
|
||||
|
||||
return { spans: result, endOfLineState: EndOfLineState.None };
|
||||
@@ -5949,6 +5968,9 @@ module ts {
|
||||
|
||||
function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType {
|
||||
let flags = symbol.getFlags();
|
||||
if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & SymbolFlags.Class) {
|
||||
return ClassificationType.className;
|
||||
@@ -5984,20 +6006,28 @@ module ts {
|
||||
*/
|
||||
function hasValueSideModule(symbol: Symbol): boolean {
|
||||
return forEach(symbol.declarations, declaration => {
|
||||
return declaration.kind === SyntaxKind.ModuleDeclaration && getModuleInstanceState(declaration) == ModuleInstanceState.Instantiated;
|
||||
return declaration.kind === SyntaxKind.ModuleDeclaration &&
|
||||
getModuleInstanceState(declaration) === ModuleInstanceState.Instantiated;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function processNode(node: Node) {
|
||||
// Only walk into nodes that intersect the requested span.
|
||||
if (node && textSpanIntersectsWith(span, node.getStart(), node.getWidth())) {
|
||||
if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) {
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (symbol) {
|
||||
let type = classifySymbol(symbol, getMeaningFromLocation(node));
|
||||
if (type) {
|
||||
pushClassification(node.getStart(), node.getWidth(), type);
|
||||
if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) {
|
||||
if (node.kind === SyntaxKind.Identifier && !nodeIsMissing(node)) {
|
||||
let identifier = <Identifier>node;
|
||||
|
||||
// Only bother calling into the typechecker if this is an identifier that
|
||||
// could possibly resolve to a type name. This makes classification run
|
||||
// in a third of the time it would normally take.
|
||||
if (classifiableNames[identifier.text]) {
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (symbol) {
|
||||
let type = classifySymbol(symbol, getMeaningFromLocation(node));
|
||||
if (type) {
|
||||
pushClassification(node.getStart(), node.getWidth(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6050,6 +6080,8 @@ module ts {
|
||||
function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
let spanStart = span.start;
|
||||
let spanLength = span.length;
|
||||
|
||||
// Make a scanner we can get trivia from.
|
||||
let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
|
||||
@@ -6066,48 +6098,55 @@ module ts {
|
||||
result.push(type);
|
||||
}
|
||||
|
||||
function classifyLeadingTrivia(token: Node): void {
|
||||
let tokenStart = skipTrivia(sourceFile.text, token.pos, /*stopAfterLineBreak:*/ false);
|
||||
if (tokenStart === token.pos) {
|
||||
return;
|
||||
}
|
||||
|
||||
// token has trivia. Classify them appropriately.
|
||||
function classifyLeadingTriviaAndGetTokenStart(token: Node): number {
|
||||
triviaScanner.setTextPos(token.pos);
|
||||
while (true) {
|
||||
let start = triviaScanner.getTextPos();
|
||||
// only bother scanning if we have something that could be trivia.
|
||||
if (!couldStartTrivia(sourceFile.text, start)) {
|
||||
return start;
|
||||
}
|
||||
|
||||
let kind = triviaScanner.scan();
|
||||
let end = triviaScanner.getTextPos();
|
||||
let width = end - start;
|
||||
|
||||
// The moment we get something that isn't trivia, then stop processing.
|
||||
if (!isTrivia(kind)) {
|
||||
return;
|
||||
return start;
|
||||
}
|
||||
|
||||
// Don't bother with newlines/whitespace.
|
||||
if (kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.WhitespaceTrivia) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only bother with the trivia if it at least intersects the span of interest.
|
||||
if (textSpanIntersectsWith(span, start, width)) {
|
||||
if (isComment(kind)) {
|
||||
classifyComment(token, kind, start, width);
|
||||
if (isComment(kind)) {
|
||||
classifyComment(token, kind, start, width);
|
||||
|
||||
// Classifying a comment might cause us to reuse the trivia scanner
|
||||
// (because of jsdoc comments). So after we classify the comment make
|
||||
// sure we set the scanner position back to where it needs to be.
|
||||
triviaScanner.setTextPos(end);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.ConflictMarkerTrivia) {
|
||||
let text = sourceFile.text;
|
||||
let ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.ConflictMarkerTrivia) {
|
||||
let text = sourceFile.text;
|
||||
let ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
// for the ======== add a comment for the first line, and then lex all
|
||||
// subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
}
|
||||
// for the ======== add a comment for the first line, and then lex all
|
||||
// subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6226,12 +6265,14 @@ module ts {
|
||||
}
|
||||
|
||||
function classifyToken(token: Node): void {
|
||||
classifyLeadingTrivia(token);
|
||||
let tokenStart = classifyLeadingTriviaAndGetTokenStart(token);
|
||||
|
||||
if (token.getWidth() > 0) {
|
||||
let tokenWidth = token.end - tokenStart;
|
||||
Debug.assert(tokenWidth >= 0);
|
||||
if (tokenWidth > 0) {
|
||||
let type = classifyTokenType(token.kind, token);
|
||||
if (type) {
|
||||
pushClassification(token.getStart(), token.getWidth(), type);
|
||||
pushClassification(tokenStart, tokenWidth, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6336,9 +6377,10 @@ module ts {
|
||||
}
|
||||
|
||||
// Ignore nodes that don't intersect the original span to classify.
|
||||
if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) {
|
||||
if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
|
||||
let children = element.getChildren(sourceFile);
|
||||
for (let child of children) {
|
||||
for (let i = 0, n = children.length; i < n; i++) {
|
||||
let child = children[i];
|
||||
if (isToken(child)) {
|
||||
classifyToken(child);
|
||||
}
|
||||
|
||||
+31
-12
@@ -19,7 +19,7 @@
|
||||
var debugObjectHost = (<any>this);
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ScriptSnapshotShim {
|
||||
/** Gets a portion of the script snapshot specified by [start, end). */
|
||||
getText(start: number, end: number): string;
|
||||
@@ -56,6 +56,7 @@ module ts {
|
||||
getDefaultLibFileName(options: string): string;
|
||||
getNewLine?(): string;
|
||||
getProjectVersion?(): string;
|
||||
useCaseSensitiveFileNames?(): boolean;
|
||||
}
|
||||
|
||||
/** Public interface of the the of a config service shim instance.*/
|
||||
@@ -233,6 +234,7 @@ module ts {
|
||||
public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
|
||||
var oldSnapshotShim = <ScriptSnapshotShimAdapter>oldSnapshot;
|
||||
var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
|
||||
// TODO: should this be '==='?
|
||||
if (encoded == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -245,16 +247,22 @@ module ts {
|
||||
|
||||
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
|
||||
private files: string[];
|
||||
private loggingEnabled = false;
|
||||
private tracingEnabled = false;
|
||||
|
||||
constructor(private shimHost: LanguageServiceShimHost) {
|
||||
}
|
||||
|
||||
public log(s: string): void {
|
||||
this.shimHost.log(s);
|
||||
if (this.loggingEnabled) {
|
||||
this.shimHost.log(s);
|
||||
}
|
||||
}
|
||||
|
||||
public trace(s: string): void {
|
||||
this.shimHost.trace(s);
|
||||
if (this.tracingEnabled) {
|
||||
this.shimHost.trace(s);
|
||||
}
|
||||
}
|
||||
|
||||
public error(s: string): void {
|
||||
@@ -270,8 +278,13 @@ module ts {
|
||||
return this.shimHost.getProjectVersion();
|
||||
}
|
||||
|
||||
public useCaseSensitiveFileNames(): boolean {
|
||||
return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
|
||||
}
|
||||
|
||||
public getCompilationSettings(): CompilerOptions {
|
||||
var settingsJson = this.shimHost.getCompilationSettings();
|
||||
// TODO: should this be '==='?
|
||||
if (settingsJson == null || settingsJson == "") {
|
||||
throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
|
||||
return null;
|
||||
@@ -344,15 +357,15 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): any {
|
||||
if (!noPerfLogging) {
|
||||
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any {
|
||||
if (logPerformance) {
|
||||
logger.log(actionDescription);
|
||||
var start = Date.now();
|
||||
}
|
||||
|
||||
var result = action();
|
||||
|
||||
if (!noPerfLogging) {
|
||||
if (logPerformance) {
|
||||
var end = Date.now();
|
||||
logger.log(actionDescription + " completed in " + (end - start) + " msec");
|
||||
if (typeof (result) === "string") {
|
||||
@@ -367,9 +380,9 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): string {
|
||||
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): string {
|
||||
try {
|
||||
var result = simpleForwardCall(logger, actionDescription, action, noPerfLogging);
|
||||
var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
|
||||
return JSON.stringify({ result: result });
|
||||
}
|
||||
catch (err) {
|
||||
@@ -408,6 +421,7 @@ module ts {
|
||||
|
||||
class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim {
|
||||
private logger: Logger;
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory,
|
||||
private host: LanguageServiceShimHost,
|
||||
@@ -417,7 +431,7 @@ module ts {
|
||||
}
|
||||
|
||||
public forwardJSONCall(actionDescription: string, action: () => any): string {
|
||||
return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false);
|
||||
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
|
||||
}
|
||||
|
||||
/// DISPOSE
|
||||
@@ -806,6 +820,7 @@ module ts {
|
||||
|
||||
class ClassifierShimObject extends ShimBase implements ClassifierShim {
|
||||
public classifier: Classifier;
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory, private logger: Logger) {
|
||||
super(factory);
|
||||
@@ -815,7 +830,7 @@ module ts {
|
||||
public getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string {
|
||||
return forwardJSONCall(this.logger, "getEncodedLexicalClassifications",
|
||||
() => convertClassifications(this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)),
|
||||
/*noPerfLogging:*/ true);
|
||||
this.logPerformance);
|
||||
}
|
||||
|
||||
/// COLORIZATION
|
||||
@@ -833,13 +848,14 @@ module ts {
|
||||
}
|
||||
|
||||
class CoreServicesShimObject extends ShimBase implements CoreServicesShim {
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory, public logger: Logger, private host: CoreServicesShimHostAdapter) {
|
||||
super(factory);
|
||||
}
|
||||
|
||||
private forwardJSONCall(actionDescription: string, action: () => any): any {
|
||||
return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false);
|
||||
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
|
||||
}
|
||||
|
||||
public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string {
|
||||
@@ -909,7 +925,7 @@ module ts {
|
||||
|
||||
export class TypeScriptServicesFactory implements ShimFactory {
|
||||
private _shims: Shim[] = [];
|
||||
private documentRegistry: DocumentRegistry = createDocumentRegistry();
|
||||
private documentRegistry: DocumentRegistry;
|
||||
|
||||
/*
|
||||
* Returns script API version.
|
||||
@@ -920,6 +936,9 @@ module ts {
|
||||
|
||||
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
|
||||
try {
|
||||
if (this.documentRegistry === undefined) {
|
||||
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
}
|
||||
var hostAdapter = new LanguageServiceShimHostAdapter(host);
|
||||
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
|
||||
return new LanguageServiceShimObject(this, host, languageService);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///<reference path='services.ts' />
|
||||
/* @internal */
|
||||
module ts.SignatureHelp {
|
||||
namespace ts.SignatureHelp {
|
||||
|
||||
// A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression
|
||||
// or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// These utilities are common to multiple language service features.
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ListItemInfo {
|
||||
listItemIndex: number;
|
||||
list: Node;
|
||||
@@ -502,7 +502,7 @@ module ts {
|
||||
|
||||
// Display-part writer helpers
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export function isFirstDeclarationOfSymbolParameter(symbol: Symbol) {
|
||||
return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user