Merge branch 'master' into tsConfigExclude

Conflicts:
	src/compiler/sys.ts
This commit is contained in:
Anders Hejlsberg
2015-06-03 15:12:13 -07:00
695 changed files with 25242 additions and 6045 deletions

View File

@@ -52,13 +52,38 @@ module ts {
}
}
export function bindSourceFile(file: SourceFile): void {
const enum ContainerFlags {
// The current node is not a container, and no container manipulation should happen before
// recursing into it.
None = 0,
// The current node is a container. It should be set as the current container (and block-
// container) before recursing into it. The current node does not have locals. Examples:
//
// Classes, ObjectLiterals, TypeLiterals, Interfaces...
IsContainer = 1 << 0,
// The current node is a block-scoped-container. It should be set as the current block-
// container before recursing into it. Examples:
//
// Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
IsBlockScopedContainer = 1 << 1,
HasLocals = 1 << 2,
// If the current node is a container that also container that also contains locals. Examples:
//
// Functions, Methods, Modules, Source-files.
IsContainerWithLocals = IsContainer | HasLocals
}
export function bindSourceFile(file: SourceFile) {
let start = new Date().getTime();
bindSourceFileWorker(file);
bindTime += new Date().getTime() - start;
}
function bindSourceFileWorker(file: SourceFile): void {
function bindSourceFileWorker(file: SourceFile) {
let parent: Node;
let container: Node;
let blockScopeContainer: Node;
@@ -67,33 +92,38 @@ module ts {
let Symbol = objectAllocator.getSymbolConstructor();
if (!file.locals) {
file.locals = {};
container = file;
setBlockScopeContainer(file, /*cleanLocals*/ false);
bind(file);
file.symbolCount = symbolCount;
}
return;
function createSymbol(flags: SymbolFlags, name: string): Symbol {
symbolCount++;
return new Symbol(flags, name);
}
function setBlockScopeContainer(node: Node, cleanLocals: boolean) {
blockScopeContainer = node;
if (cleanLocals) {
blockScopeContainer.locals = undefined;
}
}
function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags: SymbolFlags) {
symbol.flags |= symbolFlags;
function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolKind: SymbolFlags) {
symbol.flags |= symbolKind;
if (!symbol.declarations) symbol.declarations = [];
symbol.declarations.push(node);
if (symbolKind & SymbolFlags.HasExports && !symbol.exports) symbol.exports = {};
if (symbolKind & SymbolFlags.HasMembers && !symbol.members) symbol.members = {};
node.symbol = symbol;
if (symbolKind & SymbolFlags.Value && !symbol.valueDeclaration) symbol.valueDeclaration = node;
if (!symbol.declarations) {
symbol.declarations = [];
}
symbol.declarations.push(node);
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
symbol.exports = {};
}
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
symbol.members = {};
}
if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) {
symbol.valueDeclaration = node;
}
}
// Should not be called on a declaration with a computed property name,
@@ -111,12 +141,12 @@ module ts {
return (<Identifier | LiteralExpression>node.name).text;
}
switch (node.kind) {
case SyntaxKind.ConstructorType:
case SyntaxKind.Constructor:
return "__constructor";
case SyntaxKind.FunctionType:
case SyntaxKind.CallSignature:
return "__call";
case SyntaxKind.ConstructorType:
case SyntaxKind.ConstructSignature:
return "__new";
case SyntaxKind.IndexSignature:
@@ -135,7 +165,7 @@ module ts {
return node.name ? declarationNameToString(node.name) : getDeclarationName(node);
}
function declareSymbol(symbols: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
Debug.assert(!hasDynamicName(node));
// The exported symbol for an export default function/class node is always named "default"
@@ -143,7 +173,27 @@ module ts {
let symbol: Symbol;
if (name !== undefined) {
symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name));
// Check and see if the symbol table already has a symbol with this name. If not,
// create a new symbol with this name and add it to the table. Note that we don't
// give the new symbol any flags *yet*. This ensures that it will not conflict
// witht he 'excludes' flags we pass in.
//
// If we do get an existing symbol, see if it conflicts with the new symbol we're
// creating. For example, a 'var' symbol and a 'class' symbol will conflict within
// the same symbol table. If we have a conflict, report the issue on each
// declaration we have for this symbol, and then create a new symbol for this
// declaration.
//
// If we created a new symbol, either because we didn't have a symbol with this name
// in the symbol table, or we conflicted with an existing symbol, then just add this
// node as the sole declaration of the new symbol.
//
// Otherwise, we'll be merging into a compatible existing symbol (for example when
// you have multiple 'vars' with the same name in the same container). In this case
// just add this node into the declarations list of the symbol.
symbol = hasProperty(symbolTable, name)
? symbolTable[name]
: (symbolTable[name] = createSymbol(SymbolFlags.None, name));
if (symbol.flags & excludes) {
if (node.name) {
node.name.parent = node;
@@ -152,51 +202,34 @@ module ts {
// Report errors every position with duplicate declaration
// Report errors on previous encountered declarations
let message = symbol.flags & SymbolFlags.BlockScopedVariable
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
});
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
symbol = createSymbol(0, name);
symbol = createSymbol(SymbolFlags.None, name);
}
}
else {
symbol = createSymbol(0, "__missing");
symbol = createSymbol(SymbolFlags.None, "__missing");
}
addDeclarationToSymbol(symbol, node, includes);
symbol.parent = parent;
if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && symbol.exports) {
// TypeScript 1.0 spec (April 2014): 8.4
// Every class automatically contains a static property member named 'prototype',
// the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
// It is an error to explicitly declare a static property member with the name 'prototype'.
let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
if (node.name) {
node.name.parent = node;
}
file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
symbol.exports[prototypeSymbol.name] = prototypeSymbol;
prototypeSymbol.parent = symbol;
}
return symbol;
}
function declareModuleMember(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
let hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export;
if (symbolKind & SymbolFlags.Alias) {
if (symbolFlags & SymbolFlags.Alias) {
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
}
else {
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
}
}
else {
@@ -212,70 +245,172 @@ module ts {
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
if (hasExportModifier || container.flags & NodeFlags.ExportContext) {
let exportKind = (symbolKind & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
(symbolKind & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
(symbolKind & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
let exportKind =
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
(symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
let local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
node.localSymbol = local;
return local;
}
else {
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
}
}
}
// All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function
// in the type checker to validate that the local name used for a container is unique.
function bindChildren(node: Node, symbolKind: SymbolFlags, isBlockScopeContainer: boolean) {
if (symbolKind & SymbolFlags.HasLocals) {
node.locals = {};
}
// All container nodes are kept on a linked list in declaration order. This list is used by
// the getLocalNameOfContainer function in the type checker to validate that the local name
// used for a container is unique.
function bindChildren(node: Node) {
// Before we recurse into a node's chilren, we first save the existing parent, container
// and block-container. Then after we pop out of processing the children, we restore
// these saved values.
let saveParent = parent;
let saveContainer = container;
let savedBlockScopeContainer = blockScopeContainer;
// This node will now be set as the parent of all of its children as we recurse into them.
parent = node;
if (symbolKind & SymbolFlags.IsContainer) {
container = node;
// Depending on what kind of node this is, we may have to adjust the current container
// and block-container. If the current node is a container, then it is automatically
// considered the current block-container as well. Also, for containers that we know
// may contain locals, we proactively initialize the .locals field. We do this because
// it's highly likely that the .locals will be needed to place some child in (for example,
// a parameter, or variable declaration).
//
// However, we do not proactively create the .locals for block-containers because it's
// totally normal and common for block-containers to never actually have a block-scoped
// variable in them. We don't want to end up allocating an object for every 'block' we
// run into when most of them won't be necessary.
//
// Finally, if this is a block-container, then we clear out any existing .locals object
// it may contain within it. This happens in incremental scenarios. Because we can be
// reusing a node from a previous compilation, that node may have had 'locals' created
// for it. We must clear this so we don't accidently move any stale data forward from
// a previous compilation.
let containerFlags = getContainerFlags(node);
if (containerFlags & ContainerFlags.IsContainer) {
container = blockScopeContainer = node;
if (containerFlags & ContainerFlags.HasLocals) {
container.locals = {};
}
addToContainerChain(container);
}
if (isBlockScopeContainer) {
// in incremental scenarios we might reuse nodes that already have locals being allocated
// during the bind step these locals should be dropped to prevent using stale data.
// locals should always be dropped unless they were previously initialized by the binder
// these cases are:
// - node has locals (symbolKind & HasLocals) !== 0
// - node is a source file
setBlockScopeContainer(node, /*cleanLocals*/ (symbolKind & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile);
else if (containerFlags & ContainerFlags.IsBlockScopedContainer) {
blockScopeContainer = node;
blockScopeContainer.locals = undefined;
}
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
blockScopeContainer = savedBlockScopeContainer;
}
function addToContainerChain(node: Node) {
if (lastContainer) {
lastContainer.nextContainer = node;
function getContainerFlags(node: Node): ContainerFlags {
switch (node.kind) {
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.TypeLiteral:
case SyntaxKind.ObjectLiteralExpression:
return ContainerFlags.IsContainer;
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.SourceFile:
return ContainerFlags.IsContainerWithLocals;
case SyntaxKind.CatchClause:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.CaseBlock:
return ContainerFlags.IsBlockScopedContainer;
case SyntaxKind.Block:
// do not treat blocks directly inside a function as a block-scoped-container.
// Locals that reside in this block should go to the function locals. Othewise 'x'
// would not appear to be a redeclaration of a block scoped local in the following
// example:
//
// function foo() {
// var x;
// let x;
// }
//
// If we placed 'var x' into the function locals and 'let x' into the locals of
// the block, then there would be no collision.
//
// By not creating a new block-scoped-container here, we ensure that both 'var x'
// and 'let x' go into the Function-container's locals, and we do get a collision
// conflict.
return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer;
}
lastContainer = node;
return ContainerFlags.None;
}
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) {
function addToContainerChain(next: Node) {
if (lastContainer) {
lastContainer.nextContainer = next;
}
lastContainer = next;
}
function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void {
// Just call this directly so that the return type of this function stays "void".
declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes);
}
function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
switch (container.kind) {
// 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.
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, symbolKind, symbolExcludes);
break;
return declareModuleMember(node, symbolFlags, symbolExcludes);
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>container)) {
declareModuleMember(node, symbolKind, symbolExcludes);
break;
}
return declareSourceFileMember(node, symbolFlags, symbolExcludes);
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassDeclaration:
return declareClassMember(node, symbolFlags, symbolExcludes);
case SyntaxKind.EnumDeclaration:
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
case SyntaxKind.TypeLiteral:
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).
return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
@@ -289,29 +424,34 @@ module ts {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
break;
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassDeclaration:
if (node.flags & NodeFlags.Static) {
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
break;
}
case SyntaxKind.TypeLiteral:
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.InterfaceDeclaration:
declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes);
break;
case SyntaxKind.EnumDeclaration:
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
break;
// 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
// 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
// the type checker walks up the containers, checking them for matching names.
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
}
bindChildren(node, symbolKind, isBlockScopeContainer);
}
function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
return node.flags & NodeFlags.Static
? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
: declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
}
function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
return isExternalModule(file)
? declareModuleMember(node, symbolFlags, symbolExcludes)
: declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
}
function isAmbientContext(node: Node): boolean {
while (node) {
if (node.flags & NodeFlags.Ambient) return true;
if (node.flags & NodeFlags.Ambient) {
return true;
}
node = node.parent;
}
return false;
@@ -343,15 +483,16 @@ module ts {
function bindModuleDeclaration(node: ModuleDeclaration) {
setExportContextFlag(node);
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
}
else {
let state = getModuleInstanceState(node);
if (state === ModuleInstanceState.NonInstantiated) {
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true);
declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
}
else {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
if (node.symbol.constEnumOnlyModule === undefined) {
// non-merged case - use the current state
@@ -372,35 +513,27 @@ module ts {
// We do that by making an anonymous type literal symbol, and then setting the function
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
// from an actual type literal symbol you would have gotten had you used the long form.
let symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
bindChildren(node, SymbolFlags.Signature, /*isBlockScopeContainer:*/ false);
let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
typeLiteralSymbol.members = {};
typeLiteralSymbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = symbol
typeLiteralSymbol.members = { [symbol.name]: symbol };
}
function bindAnonymousDeclaration(node: Declaration, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) {
let symbol = createSymbol(symbolKind, name);
addDeclarationToSymbol(symbol, node, symbolKind);
bindChildren(node, symbolKind, isBlockScopeContainer);
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
let symbol = createSymbol(symbolFlags, name);
addDeclarationToSymbol(symbol, node, symbolFlags);
}
function bindCatchVariableDeclaration(node: CatchClause) {
bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true);
}
function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
switch (blockScopeContainer.kind) {
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, symbolKind, symbolExcludes);
declareModuleMember(node, symbolFlags, symbolExcludes);
break;
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>container)) {
declareModuleMember(node, symbolKind, symbolExcludes);
declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
// fall through.
@@ -409,9 +542,8 @@ module ts {
blockScopeContainer.locals = {};
addToContainerChain(blockScopeContainer);
}
declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes);
declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
}
bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false);
}
function bindBlockScopedVariableDeclaration(node: Declaration) {
@@ -424,187 +556,197 @@ module ts {
function bind(node: Node) {
node.parent = parent;
// 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:
//
// 1) The 'exports' table of the current container's symbol.
// 2) The 'members' table of the current container's symbol.
// 3) The 'locals' table of the current container.
//
// However, not all symbols will end up in any of these tables. 'Anonymous' symbols
// (like TypeLiterals for example) will not be put in any table.
bindWorker(node);
// Then we recurse into the children of the node to bind them as well. For certain
// symbols we do specialized work when we recurse. For example, we'll keep track of
// the current 'container' node when it changes. This helps us know which symbol table
// a local should go into for example.
bindChildren(node);
}
function bindWorker(node: Node) {
switch (node.kind) {
case SyntaxKind.TypeParameter:
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
break;
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
case SyntaxKind.Parameter:
bindParameter(<ParameterDeclaration>node);
break;
return bindParameter(<ParameterDeclaration>node);
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
if (isBindingPattern((<Declaration>node).name)) {
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
}
else if (isBlockOrCatchScoped(<Declaration>node)) {
bindBlockScopedVariableDeclaration(<Declaration>node);
}
else if (isParameterDeclaration(<VariableLikeDeclaration>node)) {
// It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
// because its parent chain has already been set up, since parents are set before descending into children.
//
// If node is a binding element in parameter declaration, we need to use ParameterExcludes.
// Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
// For example:
// function foo([a,a]) {} // Duplicate Identifier error
// function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
// // which correctly set excluded symbols
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false);
}
break;
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
case SyntaxKind.EnumMember:
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false);
break;
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Signature, SymbolFlags.None);
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
// If this is an ObjectLiteralExpression method, then it sits in the same space
// as other properties in the object literal. So we use SymbolFlags.PropertyExcludes
// so that it will conflict with any other object literal members with the same
// name.
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : 0),
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Method | ((<MethodDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None),
isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes);
case SyntaxKind.FunctionDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
break;
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
case SyntaxKind.Constructor:
bindDeclaration(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true);
break;
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None);
case SyntaxKind.GetAccessor:
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes);
case SyntaxKind.SetAccessor:
bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true);
break;
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
bindFunctionOrConstructorType(<SignatureDeclaration>node);
break;
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
case SyntaxKind.TypeLiteral:
bindAnonymousDeclaration(<TypeLiteralNode>node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false);
break;
return bindAnonymousDeclaration(<TypeLiteralNode>node, SymbolFlags.TypeLiteral, "__type");
case SyntaxKind.ObjectLiteralExpression:
bindAnonymousDeclaration(<ObjectLiteralExpression>node, SymbolFlags.ObjectLiteral, "__object", /*isBlockScopeContainer*/ false);
break;
return bindAnonymousDeclaration(<ObjectLiteralExpression>node, SymbolFlags.ObjectLiteral, "__object");
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true);
break;
return bindAnonymousDeclaration(<FunctionExpression>node, SymbolFlags.Function, "__function");
case SyntaxKind.ClassExpression:
bindAnonymousDeclaration(<ClassExpression>node, SymbolFlags.Class, "__class", /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.CatchClause:
bindCatchVariableDeclaration(<CatchClause>node);
break;
case SyntaxKind.ClassDeclaration:
bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
break;
return bindClassLikeDeclaration(<ClassLikeDeclaration>node);
case SyntaxKind.InterfaceDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);
break;
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
case SyntaxKind.TypeAliasDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false);
break;
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
case SyntaxKind.EnumDeclaration:
if (isConst(node)) {
bindDeclaration(<Declaration>node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes, /*isBlockScopeContainer*/ false);
}
break;
return bindEnumDeclaration(<EnumDeclaration>node);
case SyntaxKind.ModuleDeclaration:
bindModuleDeclaration(<ModuleDeclaration>node);
break;
return bindModuleDeclaration(<ModuleDeclaration>node);
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.NamespaceImport:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
bindDeclaration(<Declaration>node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false);
break;
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
case SyntaxKind.ImportClause:
if ((<ImportClause>node).name) {
bindDeclaration(<Declaration>node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false);
}
else {
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
}
break;
return bindImportClause(<ImportClause>node);
case SyntaxKind.ExportDeclaration:
if (!(<ExportDeclaration>node).exportClause) {
// All export * declarations are collected in an __export symbol
declareSymbol(container.symbol.exports, container.symbol, <Declaration>node, SymbolFlags.ExportStar, 0);
}
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
break;
return bindExportDeclaration(<ExportDeclaration>node);
case SyntaxKind.ExportAssignment:
if ((<ExportAssignment>node).expression.kind === SyntaxKind.Identifier) {
// An export default clause with an identifier exports all meanings of that identifier
declareSymbol(container.symbol.exports, container.symbol, <Declaration>node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}
else {
// An export default clause with an expression exports a value
declareSymbol(container.symbol.exports, container.symbol, <Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
break;
return bindExportAssignment(<ExportAssignment>node);
case SyntaxKind.SourceFile:
setExportContextFlag(<SourceFile>node);
if (isExternalModule(<SourceFile>node)) {
bindAnonymousDeclaration(<SourceFile>node, SymbolFlags.ValueModule, '"' + removeFileExtension((<SourceFile>node).fileName) + '"', /*isBlockScopeContainer*/ true);
break;
}
case SyntaxKind.Block:
// do not treat function block a block-scope container
// all block-scope locals that reside in this block should go to the function locals.
// Otherwise this won't be considered as redeclaration of a block scoped local:
// function foo() {
// let x;
// let x;
// }
// 'let x' will be placed into the function locals and 'let x' - into the locals of the block
bindChildren(node, 0, /*isBlockScopeContainer*/ !isFunctionLike(node.parent));
break;
case SyntaxKind.CatchClause:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.CaseBlock:
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
break;
default:
let saveParent = parent;
parent = node;
forEachChild(node, bind);
parent = saveParent;
return bindSourceFileIfExternalModule();
}
}
function bindSourceFileIfExternalModule() {
setExportContextFlag(file);
if (isExternalModule(file)) {
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"');
}
}
function bindExportAssignment(node: ExportAssignment) {
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);
}
else {
// An export default clause with an expression exports a value
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
}
}
function bindExportDeclaration(node: ExportDeclaration) {
if (!node.exportClause) {
// All export * declarations are collected in an __export symbol
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None);
}
}
function bindImportClause(node: ImportClause) {
if (node.name) {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
}
}
function bindClassLikeDeclaration(node: ClassLikeDeclaration) {
if (node.kind === SyntaxKind.ClassDeclaration) {
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
}
else {
bindAnonymousDeclaration(node, SymbolFlags.Class, "__class");
}
let symbol = node.symbol;
// TypeScript 1.0 spec (April 2014): 8.4
// Every class automatically contains a static property member named 'prototype', the
// type of which is an instantiation of the class type with type Any supplied as a type
// argument for each type parameter. It is an error to explicitly declare a static
// property member with the name 'prototype'.
//
// Note: we check for this here because this class may be merging into a module. The
// module might have an exported variable called 'prototype'. We can't allow that as
// that would clash with the built-in 'prototype' for the class.
let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
if (node.name) {
node.name.parent = node;
}
file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
symbol.exports[prototypeSymbol.name] = prototypeSymbol;
prototypeSymbol.parent = symbol;
}
function bindEnumDeclaration(node: EnumDeclaration) {
return isConst(node)
? bindBlockScopedDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes)
: bindBlockScopedDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes);
}
function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) {
if (!isBindingPattern(node.name)) {
if (isBlockOrCatchScoped(node)) {
bindBlockScopedVariableDeclaration(node);
}
else if (isParameterDeclaration(node)) {
// It is safe to walk up parent chain to find whether the node is a destructing parameter declaration
// because its parent chain has already been set up, since parents are set before descending into children.
//
// If node is a binding element in parameter declaration, we need to use ParameterExcludes.
// Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
// For example:
// function foo([a,a]) {} // Duplicate Identifier error
// function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
// // which correctly set excluded symbols
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
}
else {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes);
}
}
}
function bindParameter(node: ParameterDeclaration) {
if (isBindingPattern(node.name)) {
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false);
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node));
}
else {
bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
}
// If this is a property-parameter, then also declare the property symbol into the
@@ -618,13 +760,10 @@ module ts {
}
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) {
if (hasDynamicName(node)) {
bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer);
}
else {
bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer);
}
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
return hasDynamicName(node)
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -142,7 +142,7 @@ module ts {
paramType: Diagnostics.LOCATION,
},
{
name: "separateCompilation",
name: "isolatedModules",
type: "boolean",
},
{
@@ -188,10 +188,16 @@ module ts {
type: "boolean",
description: Diagnostics.Watch_input_files,
},
{
name: "experimentalDecorators",
type: "boolean",
description: Diagnostics.Enables_experimental_support_for_ES7_decorators
},
{
name: "emitDecoratorMetadata",
type: "boolean",
experimental: true
experimental: true,
description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
}
];

View File

@@ -129,6 +129,16 @@ module ts {
}
}
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
while (pos < end) {
if (array1[pos] !== array2[pos]) {
return false;
}
pos++;
}
return true;
}
/**
* Returns the last element of an array if non-empty, undefined otherwise.
*/
@@ -312,8 +322,11 @@ module ts {
Debug.assert(start >= 0, "start must be non-negative, is " + start);
Debug.assert(length >= 0, "length must be non-negative, is " + length);
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${ start } > ${ file.text.length }`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`);
if (file) {
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${ start } > ${ file.text.length }`);
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`);
}
let text = getLocaleSpecificMessage(message.key);

View File

@@ -120,7 +120,7 @@ module ts {
Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." },
Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." },
An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },
yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." },
A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." },
Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." },
A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." },
A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." },
@@ -165,8 +165,8 @@ module ts {
Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." },
Decorators_are_not_valid_here: { code: 1206, category: DiagnosticCategory.Error, key: "Decorators are not valid here." },
Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." },
Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." },
Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." },
Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." },
Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." },
Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." },
A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" },
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" },
@@ -174,6 +174,11 @@ module ts {
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." },
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." },
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." },
@@ -334,7 +339,7 @@ module ts {
The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." },
Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." },
A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." },
Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." },
Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." },
In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." },
const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." },
@@ -365,6 +370,8 @@ module ts {
A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." },
_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." },
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." },
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}'." },
@@ -449,11 +456,11 @@ module ts {
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." },
Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." },
Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." },
Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." },
Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." },
Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." },
Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." },
Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." },
Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." },
Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." },
Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." },
Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." },
Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." },
@@ -507,6 +514,9 @@ module ts {
Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." },
NEWLINE: { code: 6061, category: DiagnosticCategory.Message, key: "NEWLINE" },
Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." },
Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." },
Enables_experimental_support_for_ES7_decorators: { code: 6065, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." },
Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." },
@@ -519,9 +529,10 @@ module ts {
Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: DiagnosticCategory.Error, key: "Object literal's property '{0}' implicitly has an '{1}' type." },
Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: DiagnosticCategory.Error, key: "Rest parameter '{0}' implicitly has an 'any[]' type." },
Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: DiagnosticCategory.Error, key: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type." },
_0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." },
_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer." },
_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." },
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
@@ -535,15 +546,11 @@ module ts {
types_can_only_be_used_in_a_ts_file: { code: 8010, category: DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." },
type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." },
parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." },
can_only_be_used_in_a_ts_file: { code: 8013, category: DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." },
property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." },
enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." },
type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." },
decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." },
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
class_expressions_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'class' expressions are not currently supported." },
class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." },
};
}

View File

@@ -467,7 +467,7 @@
"category": "Error",
"code": 1162
},
"'yield' expression must be contained_within a generator declaration.": {
"A 'yield' expression is only allowed in a generator body.": {
"category": "Error",
"code": 1163
},
@@ -647,11 +647,11 @@
"category": "Error",
"code": 1207
},
"Cannot compile namespaces when the '--separateCompilation' flag is provided.": {
"Cannot compile namespaces when the '--isolatedModules' flag is provided.": {
"category": "Error",
"code": 1208
},
"Ambient const enums are not allowed when the '--separateCompilation' flag is provided.": {
"Ambient const enums are not allowed when the '--isolatedModules' flag is provided.": {
"category": "Error",
"code": 1209
},
@@ -683,6 +683,26 @@
"category": "Error",
"code": 1218
},
"Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning.": {
"category": "Error",
"code": 1219
},
"Generators are only available when targeting ECMAScript 6 or higher.": {
"category": "Error",
"code": 1220
},
"Generators are not allowed in an ambient context.": {
"category": "Error",
"code": 1221
},
"An overload signature cannot be declared as a generator.": {
"category": "Error",
"code": 1222
},
"'{0}' tag already specified.": {
"category": "Error",
"code": 1223
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -1324,7 +1344,7 @@
"category": "Error",
"code": 2471
},
"Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher.": {
"Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher.": {
"category": "Error",
"code": 2472
},
@@ -1448,6 +1468,14 @@
"category": "Error",
"code": 2503
},
"No best common type exists among yield expressions.": {
"category": "Error",
"code": 2504
},
"A generator cannot have a 'void' type annotation.": {
"category": "Error",
"code": 2505
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -1785,23 +1813,23 @@
"category": "Error",
"code": 5042
},
"Option 'sourceMap' cannot be specified with option 'separateCompilation'.": {
"Option 'sourceMap' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5043
},
"Option 'declaration' cannot be specified with option 'separateCompilation'.": {
"Option 'declaration' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5044
},
"Option 'noEmitOnError' cannot be specified with option 'separateCompilation'.": {
"Option 'noEmitOnError' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5045
},
"Option 'out' cannot be specified with option 'separateCompilation'.": {
"Option 'out' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5046
},
"Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": {
"Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": {
"category": "Error",
"code": 5047
},
@@ -2018,7 +2046,18 @@
"category": "Error",
"code": 6062
},
"Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified.": {
"category": "Error",
"code": 6064
},
"Enables experimental support for ES7 decorators.": {
"category": "Message",
"code": 6065
},
"Enables experimental support for emitting type metadata for decorators.": {
"category": "Message",
"code": 6066
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
@@ -2068,7 +2107,7 @@
"category": "Error",
"code": 7020
},
"'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer.": {
"'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.": {
"category": "Error",
"code": 7022
},
@@ -2080,6 +2119,10 @@
"category": "Error",
"code": 7024
},
"Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type.": {
"category": "Error",
"code": 7025
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@@ -2132,10 +2175,6 @@
"category": "Error",
"code": 8012
},
"'?' can only be used in a .ts file.": {
"category": "Error",
"code": 8013
},
"'property declarations' can only be used in a .ts file.": {
"category": "Error",
"code": 8014
@@ -2153,14 +2192,6 @@
"code": 8017
},
"'yield' expressions are not currently supported.": {
"category": "Error",
"code": 9000
},
"Generators are not currently supported.": {
"category": "Error",
"code": 9001
},
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
"category": "Error",
"code": 9002
@@ -2168,9 +2199,5 @@
"'class' expressions are not currently supported.": {
"category": "Error",
"code": 9003
},
"'class' declarations are only supported directly inside a module or as a top level declaration.": {
"category": "Error",
"code": 9004
}
}

View File

@@ -1366,16 +1366,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return true;
}
function emitListWithSpread(elements: Expression[], alwaysCopy: boolean, multiLine: boolean, trailingComma: boolean) {
function emitListWithSpread(elements: Expression[], needsUniqueCopy: boolean, multiLine: boolean, trailingComma: boolean, useConcat: boolean) {
let pos = 0;
let group = 0;
let length = elements.length;
while (pos < length) {
// Emit using the pattern <group0>.concat(<group1>, <group2>, ...)
if (group === 1) {
if (group === 1 && useConcat) {
write(".concat(");
}
else if (group > 1) {
else if (group > 0) {
write(", ");
}
let e = elements[pos];
@@ -1383,7 +1383,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
e = (<SpreadElementExpression>e).expression;
emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e));
pos++;
if (pos === length && group === 0 && alwaysCopy && e.kind !== SyntaxKind.ArrayLiteralExpression) {
if (pos === length && group === 0 && needsUniqueCopy && e.kind !== SyntaxKind.ArrayLiteralExpression) {
write(".slice()");
}
}
@@ -1406,7 +1406,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
group++;
}
if (group > 1) {
write(")");
if(useConcat) {
write(")");
}
}
}
@@ -1425,8 +1427,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("]");
}
else {
emitListWithSpread(elements, /*alwaysCopy*/ true, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0,
/*trailingComma*/ elements.hasTrailingComma);
emitListWithSpread(elements, /*needsUniqueCopy*/ true, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0,
/*trailingComma*/ elements.hasTrailingComma, /*useConcat*/ true);
}
}
@@ -1717,7 +1719,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
if (compilerOptions.separateCompilation) {
if (compilerOptions.isolatedModules) {
// do not inline enum values in separate compilation mode
return false;
}
@@ -1850,7 +1852,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("void 0");
}
write(", ");
emitListWithSpread(node.arguments, /*alwaysCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false);
emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false, /*useConcat*/ true);
write(")");
}
@@ -1886,11 +1888,44 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
function emitNewExpression(node: NewExpression) {
write("new ");
emit(node.expression);
if (node.arguments) {
// Spread operator logic can be 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);
//
// Could be transpiled into ES5:
//
// var arguments = [1, 2, 3, 4, 5];
// new (Array.bind.apply(Array, [void 0].concat(arguments)));
//
// `[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`.
if (languageVersion === ScriptTarget.ES5 &&
node.arguments &&
hasSpreadElement(node.arguments)) {
write("(");
emitCommaList(node.arguments);
write(")");
let target = emitCallTarget(node.expression);
write(".bind.apply(");
emit(target);
write(", [void 0].concat(");
emitListWithSpread(node.arguments, /*needsUniqueCopy*/ false, /*multiline*/ false, /*trailingComma*/ false, /*useConcat*/ false);
write(")))");
write("()");
}
else {
emit(node.expression);
if (node.arguments) {
write("(");
emitCommaList(node.arguments);
write(")");
}
}
}
@@ -2229,9 +2264,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitEmbeddedStatement(node.statement);
}
/* Returns true if start of variable declaration list was emitted.
* Return false if nothing was written - this can happen for source file level variable declarations
* in system modules - such variable declarations are hoisted.
/**
* Returns true if start of variable declaration list was emitted.
* Returns false if nothing was written - this can happen for source file level variable declarations
* in system modules where such variable declarations are hoisted.
*/
function tryEmitStartOfVariableDeclarationList(decl: VariableDeclarationList, startPos?: number): boolean {
if (shouldHoistVariable(decl, /*checkIfSourceFileLevelDecl*/ true)) {
@@ -2500,7 +2536,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write(";");
}
function emitWithStatement(node: WhileStatement) {
function emitWithStatement(node: WithStatement) {
write("with (");
emit(node.expression);
write(")");
@@ -3060,6 +3096,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
function emitVariableStatement(node: VariableStatement) {
let startIsEmitted = false;
if (node.flags & NodeFlags.Export) {
if (isES6ExportedDeclaration(node)) {
// Exported ES6 module member
@@ -3070,6 +3107,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
else {
startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
}
if (startIsEmitted) {
emitCommaList(node.declarationList.declarations);
write(";");
@@ -3085,6 +3123,28 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
}
function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node: VariableStatement) {
// If we're not exporting the variables, there's nothing special here.
// Always emit comments for these nodes.
if (!(node.flags & NodeFlags.Export)) {
return true;
}
// If we are exporting, but it's a top-level ES6 module exports,
// we'll emit the declaration list verbatim, so emit comments too.
if (isES6ExportedDeclaration(node)) {
return true;
}
// Otherwise, only emit if we have at least one initializer present.
for (let declaration of node.declarationList.declarations) {
if (declaration.initializer) {
return true;
}
}
return false;
}
function emitParameter(node: ParameterDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
if (isBindingPattern(node.name)) {
@@ -3145,7 +3205,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function emitRestParameter(node: FunctionLikeDeclaration) {
if (languageVersion < ScriptTarget.ES6 && hasRestParameters(node)) {
if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) {
let restIndex = node.parameters.length - 1;
let restParam = node.parameters[restIndex];
@@ -3273,7 +3333,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("(");
if (node) {
let parameters = node.parameters;
let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameters(node) ? 1 : 0;
let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0;
emitList(parameters, 0, parameters.length - omitCount, /*multiLine*/ false, /*trailingComma*/ false);
}
write(")");
@@ -4370,7 +4430,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
function shouldEmitEnumDeclaration(node: EnumDeclaration) {
let isConstEnum = isConst(node);
return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation;
return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules;
}
function emitEnumDeclaration(node: EnumDeclaration) {
@@ -4475,7 +4535,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function shouldEmitModuleDeclaration(node: ModuleDeclaration) {
return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation);
return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
}
function isModuleMergedWithES6Class(node: ModuleDeclaration) {
@@ -5684,7 +5744,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
}
if (isExternalModule(node) || compilerOptions.separateCompilation) {
if (isExternalModule(node) || compilerOptions.isolatedModules) {
if (languageVersion >= ScriptTarget.ES6) {
emitES6Module(node, startIndex);
}
@@ -5747,6 +5807,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
case SyntaxKind.ExportAssignment:
return false;
case SyntaxKind.VariableStatement:
return shouldEmitLeadingAndTrailingCommentsForVariableStatement(<VariableStatement>node);
case SyntaxKind.ModuleDeclaration:
// Only emit the leading/trailing comments for a module if we're actually
// emitting the module as well.

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ module ts {
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
export const version = "1.5.2";
export const version = "1.5.3";
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
@@ -534,21 +534,21 @@ module ts {
}
function verifyCompilerOptions() {
if (options.separateCompilation) {
if (options.isolatedModules) {
if (options.sourceMap) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules));
}
if (options.declaration) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules));
}
if (options.noEmitOnError) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules));
}
if (options.out) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules));
}
}
@@ -585,15 +585,15 @@ module ts {
let languageVersion = options.target || ScriptTarget.ES3;
let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
if (options.separateCompilation) {
if (options.isolatedModules) {
if (!options.module && languageVersion < ScriptTarget.ES6) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher));
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher));
}
let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined);
if (firstNonExternalModuleSourceFile) {
let span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided));
diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
}
}
else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) {
@@ -640,6 +640,11 @@ module ts {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration));
}
}
if (options.emitDecoratorMetadata &&
!options.experimentalDecorators) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified));
}
}
}
}

View File

@@ -598,12 +598,26 @@ module ts {
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
}
/** Creates a scanner over a (possibly unspecified) range of a piece of text. */
export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner {
let pos: number; // Current position (end position of text of current token)
let end: number; // end of text
let startPos: number; // Start position of whitespace before current token
let tokenPos: number; // Start position of text of current token
/* @internal */
// Creates a scanner over a (possibly unspecified) range of a piece of text.
export function createScanner(languageVersion: ScriptTarget,
skipTrivia: boolean,
text?: string,
onError?: ErrorCallback,
start?: number,
length?: number): Scanner {
// Current position (end position of text of current token)
let pos: number;
// end of text
let end: number;
// Start position of whitespace before current token
let startPos: number;
// Start position of text of current token
let tokenPos: number;
let token: SyntaxKind;
let tokenValue: string;
let precedingLineBreak: boolean;

View File

@@ -246,7 +246,7 @@ module ts {
for (let current of files) {
var name = combinePaths(path, current);
if (!contains(exclude, getCanonicalPath(name))) {
var stat = _fs.lstatSync(name);
var stat = _fs.statSync(name);
if (stat.isFile()) {
if (!extension || fileExtensionIs(name, extension)) {
result.push(name);

View File

@@ -270,6 +270,32 @@ module ts {
// Top-level nodes
SourceFile,
// JSDoc nodes.
JSDocTypeExpression,
// The * type.
JSDocAllType,
// The ? type.
JSDocUnknownType,
JSDocArrayType,
JSDocUnionType,
JSDocTupleType,
JSDocNullableType,
JSDocNonNullableType,
JSDocRecordType,
JSDocRecordMember,
JSDocTypeReference,
JSDocOptionalType,
JSDocFunctionType,
JSDocVariadicType,
JSDocConstructorType,
JSDocThisType,
JSDocComment,
JSDocTag,
JSDocParameterTag,
JSDocReturnTag,
JSDocTypeTag,
JSDocTemplateTag,
// Synthesized list
SyntaxList,
// Enum value count
@@ -324,6 +350,8 @@ module ts {
/* @internal */
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,
@@ -345,6 +373,10 @@ module ts {
// error.
ThisNodeHasError = 1 << 5,
// This node was parsed in a JavaScript file and can be processed differently. For example
// its type can be specified usign a JSDoc comment.
JavaScriptFile = 1 << 6,
// Context flags set directly by the parser.
ParserGeneratedFlags = StrictMode | DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError,
@@ -352,10 +384,10 @@ module ts {
// Used during incremental parsing to determine if this node or any of its children had an
// error. Computed only once and then cached.
ThisNodeOrAnySubNodesHasError = 1 << 6,
ThisNodeOrAnySubNodesHasError = 1 << 7,
// Used to know if we've computed data from children and cached it in this node.
HasAggregatedChildData = 1 << 7
HasAggregatedChildData = 1 << 8
}
/* @internal */
@@ -371,14 +403,15 @@ module ts {
// Specific context the parser was in when this node was created. Normally undefined.
// Only set when the parser was in some interesting context (like async/yield).
/* @internal */ parserContextFlags?: ParserContextFlags;
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding)
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding
/* @internal */ jsDocComment?: JSDocComment; // JSDoc for the node, if it has any. Only for .js files.
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
}
export interface NodeArray<T> extends Array<T>, TextRange {
@@ -660,7 +693,7 @@ module ts {
export interface YieldExpression extends Expression {
asteriskToken?: Node;
expression: Expression;
expression?: Expression;
}
export interface BinaryExpression extends Expression {
@@ -884,7 +917,7 @@ module ts {
_classElementBrand: any;
}
export interface InterfaceDeclaration extends Declaration, ModuleElement {
export interface InterfaceDeclaration extends Declaration, Statement {
name: Identifier;
typeParameters?: NodeArray<TypeParameterDeclaration>;
heritageClauses?: NodeArray<HeritageClause>;
@@ -896,7 +929,7 @@ module ts {
types?: NodeArray<ExpressionWithTypeArguments>;
}
export interface TypeAliasDeclaration extends Declaration, ModuleElement {
export interface TypeAliasDeclaration extends Declaration, Statement {
name: Identifier;
type: TypeNode;
}
@@ -908,7 +941,7 @@ module ts {
initializer?: Expression;
}
export interface EnumDeclaration extends Declaration, ModuleElement {
export interface EnumDeclaration extends Declaration, Statement {
name: Identifier;
members: NodeArray<EnumMember>;
}
@@ -992,6 +1025,106 @@ module ts {
kind: SyntaxKind;
}
// represents a top level: { type } expression in a JSDoc comment.
export interface JSDocTypeExpression extends Node {
type: JSDocType;
}
export interface JSDocType extends TypeNode {
_jsDocTypeBrand: any;
}
export interface JSDocAllType extends JSDocType {
_JSDocAllTypeBrand: any;
}
export interface JSDocUnknownType extends JSDocType {
_JSDocUnknownTypeBrand: any;
}
export interface JSDocArrayType extends JSDocType {
elementType: JSDocType;
}
export interface JSDocUnionType extends JSDocType {
types: NodeArray<JSDocType>;
}
export interface JSDocTupleType extends JSDocType {
types: NodeArray<JSDocType>;
}
export interface JSDocNonNullableType extends JSDocType {
type: JSDocType;
}
export interface JSDocNullableType extends JSDocType {
type: JSDocType;
}
export interface JSDocRecordType extends JSDocType, TypeLiteralNode {
members: NodeArray<JSDocRecordMember>;
}
export interface JSDocTypeReference extends JSDocType {
name: EntityName;
typeArguments: NodeArray<JSDocType>
}
export interface JSDocOptionalType extends JSDocType {
type: JSDocType;
}
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
parameters: NodeArray<ParameterDeclaration>;
type: JSDocType;
}
export interface JSDocVariadicType extends JSDocType {
type: JSDocType;
}
export interface JSDocConstructorType extends JSDocType {
type: JSDocType;
}
export interface JSDocThisType extends JSDocType {
type: JSDocType;
}
export interface JSDocRecordMember extends PropertyDeclaration {
name: Identifier | LiteralExpression,
type?: JSDocType
}
export interface JSDocComment extends Node {
tags: NodeArray<JSDocTag>;
}
export interface JSDocTag extends Node {
atToken: Node;
tagName: Identifier;
}
export interface JSDocTemplateTag extends JSDocTag {
typeParameters: NodeArray<TypeParameterDeclaration>;
}
export interface JSDocReturnTag extends JSDocTag {
typeExpression: JSDocTypeExpression;
}
export interface JSDocTypeTag extends JSDocTag {
typeExpression: JSDocTypeExpression;
}
export interface JSDocParameterTag extends JSDocTag {
preParameterName?: Identifier;
typeExpression?: JSDocTypeExpression;
postParameterName?: Identifier;
isBracketed: boolean;
}
// Source files are declarations when they are external modules.
export interface SourceFile extends Declaration {
statements: NodeArray<ModuleElement>;
@@ -1287,6 +1420,7 @@ module ts {
}
export const enum SymbolFlags {
None = 0,
FunctionScopedVariable = 0x00000001, // Variable (var) or parameter
BlockScopedVariable = 0x00000002, // A block-scoped variable (let or const)
Property = 0x00000004, // Property or enum member
@@ -1356,11 +1490,9 @@ module ts {
ExportHasLocal = Function | Class | Enum | ValueModule,
HasLocals = Function | Module | Method | Constructor | Accessor | Signature,
HasExports = Class | Enum | Module,
HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,
IsContainer = HasLocals | HasExports | HasMembers,
PropertyOrAccessor = Property | Accessor,
Export = ExportNamespace | ExportType | ExportValue,
}
@@ -1368,14 +1500,15 @@ module ts {
export interface Symbol {
flags: SymbolFlags; // Symbol flags
name: string; // Name of symbol
/* @internal */ id?: number; // Unique id (used to look up SymbolLinks)
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
declarations?: Declaration[]; // Declarations associated with this symbol
/* @internal */ parent?: Symbol; // Parent symbol
valueDeclaration?: Declaration; // First value declaration of the symbol
members?: SymbolTable; // Class, interface or literal instance members
exports?: SymbolTable; // Module exports
/* @internal */ id?: number; // Unique id (used to look up SymbolLinks)
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
/* @internal */ parent?: Symbol; // Parent symbol
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
valueDeclaration?: Declaration; // First value declaration of the symbol
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
}
@@ -1449,14 +1582,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
ContainsUndefinedOrNull = 0x00080000, // 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
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,
@@ -1493,6 +1627,8 @@ module ts {
// Class and interface types (TypeFlags.Class and TypeFlags.Interface)
export interface InterfaceType extends ObjectType {
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 {
@@ -1539,8 +1675,15 @@ module ts {
properties: Symbol[]; // Properties
callSignatures: Signature[]; // Call signatures of type
constructSignatures: Signature[]; // Construct signatures of type
stringIndexType: Type; // String index type
numberIndexType: Type; // Numeric index type
stringIndexType?: Type; // String index type
numberIndexType?: Type; // Numeric index type
}
// Just a place to cache element types of iterables and iterators
/* @internal */
export interface IterableOrIteratorType extends ObjectType, UnionType {
iterableElementType?: Type;
iteratorElementType?: Type;
}
// Type parameters (TypeFlags.TypeParameter)
@@ -1676,7 +1819,8 @@ module ts {
target?: ScriptTarget;
version?: boolean;
watch?: boolean;
separateCompilation?: boolean;
isolatedModules?: boolean;
experimentalDecorators?: boolean;
emitDecoratorMetadata?: boolean;
/* @internal */ stripInternal?: boolean;
[option: string]: string | number | boolean;

View File

@@ -408,6 +408,93 @@ module ts {
export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/
export function isTypeNode(node: Node): boolean {
if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) {
return true;
}
switch (node.kind) {
case SyntaxKind.AnyKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
return true;
case SyntaxKind.VoidKeyword:
return node.parent.kind !== SyntaxKind.VoidExpression;
case SyntaxKind.StringLiteral:
// Specialized signatures can have string literals as their parameters' type names
return node.parent.kind === SyntaxKind.Parameter;
case SyntaxKind.ExpressionWithTypeArguments:
return true;
// Identifiers and qualified names may be type nodes, depending on their context. Climb
// above them to find the lowest container
case SyntaxKind.Identifier:
// If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
if (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node) {
node = node.parent;
}
else if (node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node) {
node = node.parent;
}
// fall through
case SyntaxKind.QualifiedName:
case SyntaxKind.PropertyAccessExpression:
// At this point, node is either a qualified name or an identifier
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression,
"'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'.");
let parent = node.parent;
if (parent.kind === SyntaxKind.TypeQuery) {
return false;
}
// Do not recursively call isTypeNode on the parent. In the example:
//
// let a: A.B.C;
//
// Calling isTypeNode would consider the qualified name A.B a type node. Only C or
// A.B.C is a type node.
if (SyntaxKind.FirstTypeNode <= parent.kind && parent.kind <= SyntaxKind.LastTypeNode) {
return true;
}
switch (parent.kind) {
case SyntaxKind.ExpressionWithTypeArguments:
return true;
case SyntaxKind.TypeParameter:
return node === (<TypeParameterDeclaration>parent).constraint;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
return node === (<VariableLikeDeclaration>parent).type;
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.Constructor:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return node === (<FunctionLikeDeclaration>parent).type;
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
return node === (<SignatureDeclaration>parent).type;
case SyntaxKind.TypeAssertionExpression:
return node === (<TypeAssertion>parent).type;
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
return (<CallExpression>parent).typeArguments && indexOf((<CallExpression>parent).typeArguments, node) >= 0;
case SyntaxKind.TaggedTemplateExpression:
// TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
return false;
}
}
return false;
}
// Warning: This has the same semantics as the forEach family of functions,
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
export function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T {
@@ -438,6 +525,46 @@ module ts {
}
}
export function forEachYieldExpression(body: Block, visitor: (expr: YieldExpression) => void): void {
return traverse(body);
function traverse(node: Node): void {
switch (node.kind) {
case SyntaxKind.YieldExpression:
visitor(<YieldExpression>node);
let operand = (<YieldExpression>node).expression;
if (operand) {
traverse(operand);
}
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.ClassDeclaration:
// These are not allowed inside a generator now, but eventually they may be allowed
// as local types. Regardless, any yield statements contained within them should be
// skipped in this traversal.
return;
default:
if (isFunctionLike(node)) {
let name = (<FunctionLikeDeclaration>node).name;
if (name && name.kind === SyntaxKind.ComputedPropertyName) {
// Note that we will not include methods/accessors of a class because they would require
// first descending into the class. This is by design.
traverse((<ComputedPropertyName>name).expression);
return;
}
}
else if (!isTypeNode(node)) {
// This is the general case, which should include mostly expressions and statements.
// Also includes NodeArrays.
forEachChild(node, traverse);
}
}
}
}
export function isVariableLike(node: Node): boolean {
if (node) {
switch (node.kind) {
@@ -468,6 +595,12 @@ module ts {
return false;
}
export function isClassLike(node: Node): boolean {
if (node) {
return node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression;
}
}
export function isFunctionLike(node: Node): boolean {
if (node) {
switch (node.kind) {
@@ -733,6 +866,7 @@ module ts {
case SyntaxKind.TemplateExpression:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.OmittedExpression:
case SyntaxKind.YieldExpression:
return true;
case SyntaxKind.QualifiedName:
while (node.parent.kind === SyntaxKind.QualifiedName) {
@@ -829,10 +963,6 @@ module ts {
}
}
export function hasDotDotDotToken(node: Node) {
return node && node.kind === SyntaxKind.Parameter && (<ParameterDeclaration>node).dotDotDotToken !== undefined;
}
export function hasQuestionToken(node: Node) {
if (node) {
switch (node.kind) {
@@ -852,8 +982,76 @@ module ts {
return false;
}
export function hasRestParameters(s: SignatureDeclaration): boolean {
return s.parameters.length > 0 && lastOrUndefined(s.parameters).dotDotDotToken !== undefined;
export function isJSDocConstructSignature(node: Node) {
return node.kind === SyntaxKind.JSDocFunctionType &&
(<JSDocFunctionType>node).parameters.length > 0 &&
(<JSDocFunctionType>node).parameters[0].type.kind === SyntaxKind.JSDocConstructorType;
}
function getJSDocTag(node: Node, kind: SyntaxKind): JSDocTag {
if (node && node.jsDocComment) {
for (let tag of node.jsDocComment.tags) {
if (tag.kind === kind) {
return tag;
}
}
}
}
export function getJSDocTypeTag(node: Node): JSDocTypeTag {
return <JSDocTypeTag>getJSDocTag(node, SyntaxKind.JSDocTypeTag);
}
export function getJSDocReturnTag(node: Node): JSDocReturnTag {
return <JSDocReturnTag>getJSDocTag(node, SyntaxKind.JSDocReturnTag);
}
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
return <JSDocTemplateTag>getJSDocTag(node, SyntaxKind.JSDocTemplateTag);
}
export function getCorrespondingJSDocParameterTag(parameter: ParameterDeclaration): JSDocParameterTag {
if (parameter.name && parameter.name.kind === SyntaxKind.Identifier) {
// If it's a parameter, see if the parent has a jsdoc comment with an @param
// annotation.
let parameterName = (<Identifier>parameter.name).text;
let docComment = parameter.parent.jsDocComment;
if (docComment) {
return <JSDocParameterTag>forEach(docComment.tags, t => {
if (t.kind === SyntaxKind.JSDocParameterTag) {
let parameterTag = <JSDocParameterTag>t;
let name = parameterTag.preParameterName || parameterTag.postParameterName;
if (name.text === parameterName) {
return t;
}
}
});
}
}
}
export function hasRestParameter(s: SignatureDeclaration): boolean {
return isRestParameter(lastOrUndefined(s.parameters));
}
export function isRestParameter(node: ParameterDeclaration) {
if (node) {
if (node.parserContextFlags & ParserContextFlags.JavaScriptFile) {
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
return true;
}
let paramTag = getCorrespondingJSDocParameterTag(node);
if (paramTag && paramTag.typeExpression) {
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
}
}
return node.dotDotDotToken !== undefined;
}
return false;
}
export function isLiteralKind(kind: SyntaxKind): boolean {
@@ -1447,7 +1645,7 @@ module ts {
if ((isExternalModule(sourceFile) || !compilerOptions.out)) {
// 1. in-browser single file compilation scenario
// 2. non .js file
return compilerOptions.separateCompilation || !fileExtensionIs(sourceFile.fileName, ".js");
return compilerOptions.isolatedModules || !fileExtensionIs(sourceFile.fileName, ".js");
}
return false;
}
@@ -1707,6 +1905,10 @@ module ts {
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined;
}
export function isJavaScript(fileName: string) {
return fileExtensionIs(fileName, ".js");
}
/**
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences
* representing the UTF-8 encoding of the character, and return the expanded char code list.
@@ -2000,4 +2202,14 @@ module ts {
return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength:*/ newEndN - oldStartN);
}
export function getTypeParameterOwner(d: Declaration): Declaration {
if (d && d.kind === SyntaxKind.TypeParameter) {
for (let current: Node = d; current; current = current.parent) {
if (isFunctionLike(current) || isClassLike(current) || current.kind === SyntaxKind.InterfaceDeclaration) {
return <Declaration>current;
}
}
}
}
}