Merge pull request #6892 from Microsoft/transforms-visitor

Adds the visitor API foundation for tree transformations.
This commit is contained in:
Ron Buckton
2016-03-18 16:40:18 -07:00
265 changed files with 18892 additions and 3953 deletions
+35
View File
@@ -40,7 +40,20 @@ var compilerSources = [
"utilities.ts",
"binder.ts",
"checker.ts",
"factory.ts",
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es6.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/es7.ts",
"transformers/es6.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
"printer.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
@@ -60,7 +73,20 @@ var servicesSources = [
"utilities.ts",
"binder.ts",
"checker.ts",
"factory.ts",
"visitor.ts",
"transformers/destructuring.ts",
"transformers/ts.ts",
"transformers/module/es6.ts",
"transformers/module/system.ts",
"transformers/module/module.ts",
"transformers/jsx.ts",
"transformers/es7.ts",
"transformers/es6.ts",
"transformer.ts",
"sourcemap.ts",
"comments.ts",
"printer.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
@@ -212,6 +238,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
}
var useDebugMode = true;
var useTransforms = process.env.USE_TRANSFORMS || false;
var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node");
var compilerFilename = "tsc.js";
var LKGCompiler = path.join(LKGDirectory, compilerFilename);
@@ -271,6 +298,10 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu
options += " --stripInternal"
}
if (useBuiltCompiler && useTransforms) {
options += " --experimentalTransforms"
}
var cmd = host + " " + compilerPath + " " + options + " ";
cmd = cmd + sources.join(" ");
console.log(cmd + "\n");
@@ -394,6 +425,10 @@ task("setDebugMode", function() {
useDebugMode = true;
});
task("setTransforms", function() {
useTransforms = true;
});
task("configure-nightly", [configureNightlyJs], function() {
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs;
console.log(cmd);
+600 -9
View File
@@ -37,7 +37,7 @@ namespace ts {
return ModuleInstanceState.ConstEnumOnly;
}
// 3. non-exported import declarations
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(node.flags & NodeFlags.Export)) {
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(hasModifier(node, ModifierFlags.Export))) {
return ModuleInstanceState.NonInstantiated;
}
// 4. other uninstantiated module declarations.
@@ -132,11 +132,16 @@ namespace ts {
let Symbol: { new (flags: SymbolFlags, name: string): Symbol };
let classifiableNames: Map<string>;
// state used to aggregate transform flags during bind.
let subtreeTransformFlags: TransformFlags = TransformFlags.None;
let skipTransformFlagAggregation: boolean;
function bindSourceFile(f: SourceFile, opts: CompilerOptions) {
file = f;
options = opts;
inStrictMode = !!file.externalModuleIndicator;
classifiableNames = {};
skipTransformFlagAggregation = isDeclarationFile(file);
Symbol = objectAllocator.getSymbolConstructor();
@@ -161,6 +166,7 @@ namespace ts {
hasAsyncFunctions = false;
hasDecorators = false;
hasParameterDecorators = false;
subtreeTransformFlags = TransformFlags.None;
}
return bindSourceFile;
@@ -250,7 +256,7 @@ namespace ts {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
return node.flags & NodeFlags.Default ? "default" : undefined;
return hasModifier(node, ModifierFlags.Default) ? "default" : undefined;
case SyntaxKind.JSDocFunctionType:
return isJSDocConstructSignature(node) ? "__new" : "__call";
case SyntaxKind.Parameter:
@@ -278,7 +284,7 @@ namespace ts {
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
Debug.assert(!hasDynamicName(node));
const isDefaultExport = node.flags & NodeFlags.Default;
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
// The exported symbol for an export default function/class node is always named "default"
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
@@ -323,7 +329,7 @@ namespace ts {
: Diagnostics.Duplicate_identifier_0;
forEach(symbol.declarations, declaration => {
if (declaration.flags & NodeFlags.Default) {
if (hasModifier(declaration, ModifierFlags.Default)) {
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
}
});
@@ -347,7 +353,7 @@ namespace ts {
}
function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
const hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export;
const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export;
if (symbolFlags & SymbolFlags.Alias) {
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
@@ -856,7 +862,7 @@ namespace ts {
}
function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
return node.flags & NodeFlags.Static
return hasModifier(node, ModifierFlags.Static)
? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
: declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
}
@@ -893,7 +899,7 @@ namespace ts {
function bindModuleDeclaration(node: ModuleDeclaration) {
setExportContextFlag(node);
if (isAmbientModule(node)) {
if (node.flags & NodeFlags.Export) {
if (hasModifier(node, ModifierFlags.Export)) {
errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
}
declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
@@ -1178,7 +1184,20 @@ namespace ts {
// 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);
if (skipTransformFlagAggregation) {
bindChildren(node);
}
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
skipTransformFlagAggregation = true;
bindChildren(node);
skipTransformFlagAggregation = false;
}
else {
const savedSubtreeTransformFlags = subtreeTransformFlags;
subtreeTransformFlags = 0;
bindChildren(node);
subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
}
inStrictMode = savedInStrictMode;
}
@@ -1696,7 +1715,9 @@ namespace ts {
case Reachability.Unreachable:
const reportError =
// report error on all statements except empty ones
(isStatement(node) && node.kind !== SyntaxKind.EmptyStatement) ||
(isStatementButNotDeclaration(node) && node.kind !== SyntaxKind.EmptyStatement) ||
// report error on ExportAssignment
node.kind === SyntaxKind.ExportAssignment ||
// report error on class declarations
node.kind === SyntaxKind.ClassDeclaration ||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
@@ -1751,4 +1772,574 @@ namespace ts {
implicitLabels = [];
}
}
/**
* Computes the transform flags for a node, given the transform flags of its subtree
*
* @param node The node to analyze
* @param subtreeFlags Transform flags computed for this node's subtree
*/
export function computeTransformFlagsForNode(node: Node, subtreeFlags: TransformFlags): TransformFlags {
// Mark transformations needed for each node
let transformFlags = TransformFlags.None;
let excludeFlags = TransformFlags.None;
switch (node.kind) {
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.AbstractKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.AwaitExpression:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.EnumMember:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.ReadonlyKeyword:
// These nodes are TypeScript syntax.
transformFlags = TransformFlags.AssertTypeScript;
break;
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxText:
case SyntaxKind.JsxClosingElement:
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxSpreadAttribute:
case SyntaxKind.JsxExpression:
// These nodes are Jsx syntax.
transformFlags = TransformFlags.AssertJsx;
break;
case SyntaxKind.ExportKeyword:
// This node is both ES6 and TypeScript syntax.
transformFlags = TransformFlags.AssertES6 | TransformFlags.TypeScript;
break;
case SyntaxKind.DefaultKeyword:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
case SyntaxKind.TemplateTail:
case SyntaxKind.TemplateExpression:
case SyntaxKind.TaggedTemplateExpression:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.ForOfStatement:
case SyntaxKind.YieldExpression:
// These nodes are ES6 syntax.
transformFlags = TransformFlags.AssertES6;
break;
case SyntaxKind.AnyKeyword:
case SyntaxKind.NumberKeyword:
case SyntaxKind.StringKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.TypeParameter:
case SyntaxKind.PropertySignature:
case SyntaxKind.MethodSignature:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.TypePredicate:
case SyntaxKind.TypeReference:
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeLiteral:
case SyntaxKind.ArrayType:
case SyntaxKind.TupleType:
case SyntaxKind.UnionType:
case SyntaxKind.IntersectionType:
case SyntaxKind.ParenthesizedType:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteralType:
// Types and signatures are TypeScript syntax, and exclude all other facts.
subtreeFlags = TransformFlags.None;
excludeFlags = TransformFlags.TypeExcludes;
transformFlags = TransformFlags.AssertTypeScript;
break;
case SyntaxKind.ComputedPropertyName:
// Even though computed property names are ES6, we don't treat them as such.
// This is so that they can flow through PropertyName transforms unaffected.
// Instead, we mark the container as ES6, so that it can properly handle the transform.
transformFlags = TransformFlags.ContainsComputedPropertyName;
break;
case SyntaxKind.SpreadElementExpression:
// This node is ES6 syntax, but is handled by a containing node.
transformFlags = TransformFlags.ContainsSpreadElementExpression;
break;
case SyntaxKind.SuperKeyword:
// This node is ES6 syntax.
transformFlags = TransformFlags.AssertES6;
break;
case SyntaxKind.ThisKeyword:
// Mark this node and its ancestors as containing a lexical `this` keyword.
transformFlags = TransformFlags.ContainsLexicalThis;
break;
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
// These nodes are ES6 syntax.
transformFlags = TransformFlags.AssertES6;
break;
case SyntaxKind.Decorator:
// This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
transformFlags = TransformFlags.AssertTypeScript | TransformFlags.ContainsDecorators;
break;
case SyntaxKind.ObjectLiteralExpression:
excludeFlags = TransformFlags.ObjectLiteralExcludes;
if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) {
// If an ObjectLiteralExpression contains a ComputedPropertyName, then it
// is an ES6 node.
transformFlags = TransformFlags.AssertES6;
}
break;
case SyntaxKind.CallExpression:
return computeCallExpression(<CallExpression>node, subtreeFlags);
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.NewExpression:
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
// If the this node contains a SpreadElementExpression, then it is an ES6
// node.
transformFlags = TransformFlags.AssertES6;
}
break;
case SyntaxKind.ModuleDeclaration:
// An ambient declaration is TypeScript syntax.
if (hasModifier(node, ModifierFlags.Ambient)) {
subtreeFlags = TransformFlags.None;
}
// This node is TypeScript syntax, and excludes markers that should not escape the module scope.
excludeFlags = TransformFlags.ModuleExcludes;
transformFlags = TransformFlags.AssertTypeScript;
break;
case SyntaxKind.ParenthesizedExpression:
return computeParenthesizedExpression(<ParenthesizedExpression>node, subtreeFlags);
case SyntaxKind.BinaryExpression:
return computeBinaryExpression(<BinaryExpression>node, subtreeFlags);
case SyntaxKind.ExpressionStatement:
// If the expression of an expression statement is a destructuring assignment,
// then we treat the statement as ES6 so that we can indicate that we do not
// need to hold on to the right-hand side.
if ((<ExpressionStatement>node).expression.transformFlags & TransformFlags.DestructuringAssignment) {
transformFlags = TransformFlags.AssertES6;
}
break;
case SyntaxKind.Parameter:
return computeParameter(<ParameterDeclaration>node, subtreeFlags);
case SyntaxKind.ArrowFunction:
return computeArrowFunction(<ArrowFunction>node, subtreeFlags);
case SyntaxKind.FunctionExpression:
return computeFunctionExpression(<FunctionExpression>node, subtreeFlags);
case SyntaxKind.FunctionDeclaration:
return computeFunctionDeclaration(<FunctionDeclaration>node, subtreeFlags);
case SyntaxKind.VariableDeclaration:
return computeVariableDeclaration(<VariableDeclaration>node, subtreeFlags);
case SyntaxKind.VariableDeclarationList:
// If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
if (node.flags & NodeFlags.BlockScoped) {
transformFlags = TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
}
break;
case SyntaxKind.VariableStatement:
return computeVariableStatement(<VariableStatement>node, subtreeFlags);
case SyntaxKind.LabeledStatement:
return computeLabeledStatement(<LabeledStatement>node, subtreeFlags);
case SyntaxKind.DoStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
// A loop containing a block scoped binding *may* need to be transformed from ES6.
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) {
transformFlags = TransformFlags.AssertES6;
}
break;
case SyntaxKind.ClassDeclaration:
return computeClassDeclaration(<ClassDeclaration>node, subtreeFlags);
case SyntaxKind.ClassExpression:
return computeClassExpression(<ClassExpression>node, subtreeFlags);
case SyntaxKind.HeritageClause:
if ((<HeritageClause>node).token === SyntaxKind.ExtendsKeyword) {
// An `extends` HeritageClause is ES6 syntax.
transformFlags = TransformFlags.AssertES6;
}
else {
// An `implements` HeritageClause is TypeScript syntax.
Debug.assert((<HeritageClause>node).token === SyntaxKind.ImplementsKeyword);
transformFlags = TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.ExpressionWithTypeArguments:
// An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
// extends clause of a class.
transformFlags = TransformFlags.AssertES6;
// If an ExpressionWithTypeArguments contains type arguments, then it
// is TypeScript syntax.
if ((<ExpressionWithTypeArguments>node).typeArguments) {
transformFlags |= TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.Constructor:
// A Constructor is ES6 syntax.
excludeFlags = TransformFlags.ConstructorExcludes;
transformFlags = TransformFlags.AssertES6;
// An overload constructor is TypeScript syntax.
if (!(<ConstructorDeclaration>node).body) {
transformFlags |= TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.PropertyDeclaration:
// A PropertyDeclaration is TypeScript syntax.
transformFlags = TransformFlags.AssertTypeScript;
// If the PropertyDeclaration has an initializer, we need to inform its ancestor
// so that it handle the transformation.
if ((<PropertyDeclaration>node).initializer) {
transformFlags |= TransformFlags.ContainsPropertyInitializer;
}
break;
case SyntaxKind.MethodDeclaration:
// A MethodDeclaration is ES6 syntax.
excludeFlags = TransformFlags.MethodOrAccessorExcludes;
transformFlags = TransformFlags.AssertES6;
// A MethodDeclaration is TypeScript syntax if it is either async, abstract, overloaded,
// generic, or has both a computed property name and a decorator.
if ((<MethodDeclaration>node).body === undefined
|| (<MethodDeclaration>node).typeParameters !== undefined
|| hasModifier(node, ModifierFlags.Async | ModifierFlags.Abstract)
|| (subtreeFlags & TransformFlags.ContainsDecorators
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
// A GetAccessor or SetAccessor is ES5 syntax.
excludeFlags = TransformFlags.MethodOrAccessorExcludes;
// A GetAccessor or SetAccessor is TypeScript syntax if it is either abstract,
// or has both a computed property name and a decorator.
if (hasModifier(node, ModifierFlags.Abstract)
|| (subtreeFlags & TransformFlags.ContainsDecorators
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
transformFlags = TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.ImportEqualsDeclaration:
// An ImportEqualsDeclaration with a namespace reference is TypeScript.
if (!isExternalModuleImportEqualsDeclaration(node)) {
transformFlags = TransformFlags.AssertTypeScript;
}
break;
case SyntaxKind.PropertyAccessExpression:
// If a PropertyAccessExpression starts with a super keyword, then it is
// ES6 syntax, and requires a lexical `this` binding.
if ((<PropertyAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword) {
transformFlags = TransformFlags.ContainsLexicalThis;
}
break;
case SyntaxKind.SourceFile:
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
transformFlags = TransformFlags.AssertES6;
}
break;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, excludeFlags);
}
function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression
|| isSuperCall(node)
|| isSuperPropertyCall(node)) {
// If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6
// node.
transformFlags = TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ArrayLiteralOrCallOrNewExcludes);
}
function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
if (isDestructuringAssignment(node)) {
// Destructuring assignments are ES6 syntax.
transformFlags = TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment;
}
else if (isExponentiation(node)) {
// Exponentiation is ES7 syntax.
transformFlags = TransformFlags.AssertES7;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function isDestructuringAssignment(node: BinaryExpression) {
return node.operatorToken.kind === SyntaxKind.EqualsToken
&& isObjectOrArrayLiteral(node.left);
}
function isObjectOrArrayLiteral(node: Node) {
switch (node.kind) {
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.ArrayLiteralExpression:
return true;
}
return false;
}
function isExponentiation(operatorToken: Node) {
switch (operatorToken.kind) {
case SyntaxKind.AsteriskAsteriskToken:
case SyntaxKind.AsteriskAsteriskEqualsToken:
return true;
}
return false;
}
function computeParameter(node: ParameterDeclaration, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
// If the parameter has a question token, then it is TypeScript syntax.
if (isDefined(node.questionToken)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// If a parameter has an accessibility modifier, then it is TypeScript syntax.
if (hasModifier(node, ModifierFlags.AccessibilityModifier)) {
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments;
}
// If a parameter has an initializer, a binding pattern or a dotDotDot token, then
// it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
if (isDefined(node.initializer) || isDefined(node.dotDotDotToken) || isBindingPattern(node.name)) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function computeParenthesizedExpression(node: ParenthesizedExpression, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
// If the node is synthesized, it means the emitter put the parentheses there,
// not the user. If we didn't want them, the emitter would not have put them
// there.
if (node.expression.kind === SyntaxKind.AsExpression
|| node.expression.kind === SyntaxKind.TypeAssertionExpression) {
transformFlags = TransformFlags.AssertTypeScript;
}
// If the expression of a ParenthesizedExpression is a destructuring assignment,
// then the ParenthesizedExpression is a destructuring assignment.
if (node.expression.transformFlags & TransformFlags.DestructuringAssignment) {
transformFlags |= TransformFlags.DestructuringAssignment;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) {
// An ambient declaration is TypeScript syntax.
if (hasModifier(node, ModifierFlags.Ambient)) {
return updateTransformFlags(node, TransformFlags.None, TransformFlags.TypeScript, TransformFlags.ClassExcludes);
}
// A ClassDeclaration is ES6 syntax.
let transformFlags = TransformFlags.AssertES6;
// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
// An exported declaration may be TypeScript syntax.
if (subtreeFlags
& (TransformFlags.ContainsParameterPropertyAssignments
| TransformFlags.ContainsPropertyInitializer
| TransformFlags.ContainsDecorators)
|| hasModifier(node, ModifierFlags.Export)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
}
function computeClassExpression(node: ClassExpression, subtreeFlags: TransformFlags) {
// A ClassExpression is ES6 syntax.
let transformFlags = TransformFlags.AssertES6;
// A class with a parameter property assignment, property initializer, or decorator is
// TypeScript syntax.
if (subtreeFlags
& (TransformFlags.ContainsParameterPropertyAssignments
| TransformFlags.ContainsPropertyInitializer
| TransformFlags.ContainsDecorators)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
}
function computeFunctionDeclaration(node: FunctionDeclaration, subtreeFlags: TransformFlags) {
const modifiers = getModifierFlags(node);
// An ambient declaration is TypeScript syntax.
// A FunctionDeclaration without a body is an overload and is TypeScript syntax.
if (!node.body || modifiers & ModifierFlags.Ambient) {
return updateTransformFlags(node, TransformFlags.None, TransformFlags.AssertTypeScript, TransformFlags.FunctionExcludes);
}
let transformFlags = TransformFlags.None;
// If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax.
if (modifiers & ModifierFlags.Export) {
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES6;
}
// If a FunctionDeclaration has an asterisk token, is exported, or its
// subtree has marked the container as needing to capture the lexical `this`,
// then this node is ES6 syntax.
if (subtreeFlags & (TransformFlags.ContainsCapturedLexicalThis | TransformFlags.ContainsDefaultValueAssignments)
|| node.asteriskToken) {
transformFlags |= TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.FunctionExcludes);
}
function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
// An async function expression is TypeScript syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// If a FunctionExpression contains an asterisk token, or its subtree has marked the container
// as needing to capture the lexical this, then this node is ES6 syntax.
if (subtreeFlags & (TransformFlags.ContainsCapturedLexicalThis | TransformFlags.ContainsDefaultValueAssignments)
|| node.asteriskToken) {
transformFlags |= TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.FunctionExcludes);
}
function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) {
// An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
let transformFlags = TransformFlags.AssertES6;
// An async arrow function is TypeScript syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ArrowFunctionExcludes);
}
function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
// A VariableDeclaration with a binding pattern is ES6 syntax.
if (isBindingPattern((<VariableDeclaration>node).name)) {
transformFlags = TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function computeVariableStatement(node: VariableStatement, subtreeFlags: TransformFlags) {
const modifiers = getModifierFlags(node);
// An ambient declaration is TypeScript syntax.
if (modifiers & ModifierFlags.Ambient) {
return updateTransformFlags(node, TransformFlags.None, TransformFlags.AssertTypeScript, TransformFlags.None);
}
let transformFlags = TransformFlags.None;
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
if (modifiers & ModifierFlags.Export) {
transformFlags = TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function computeLabeledStatement(node: LabeledStatement, subtreeFlags: TransformFlags) {
let transformFlags = TransformFlags.None;
// A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding
&& isIterationStatement(this, /*lookInLabeledStatements*/ true)) {
transformFlags = TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
function updateTransformFlags(node: Node, subtreeFlags: TransformFlags, transformFlags: TransformFlags, excludeFlags: TransformFlags) {
node.transformFlags = transformFlags | subtreeFlags | TransformFlags.HasComputedFlags;
node.excludeTransformFlags = excludeFlags | TransformFlags.NodeExcludes;
return node.transformFlags & ~node.excludeTransformFlags;
}
}
+138 -133
View File
@@ -535,7 +535,7 @@ namespace ts {
const initializerOfNonStaticProperty = current.parent &&
current.parent.kind === SyntaxKind.PropertyDeclaration &&
(current.parent.flags & NodeFlags.Static) === 0 &&
(getModifierFlags(current.parent) & ModifierFlags.Static) === 0 &&
(<PropertyDeclaration>current.parent).initializer === current;
if (initializerOfNonStaticProperty) {
@@ -653,7 +653,7 @@ namespace ts {
// local variables of the constructor. This effectively means that entities from outer scopes
// by the same name as a constructor parameter or local variable are inaccessible
// in initializer expressions for instance member variables.
if (isClassLike(location.parent) && !(location.flags & NodeFlags.Static)) {
if (isClassLike(location.parent) && !(getModifierFlags(location) & ModifierFlags.Static)) {
const ctor = findConstructorDeclaration(<ClassLikeDeclaration>location.parent);
if (ctor && ctor.locals) {
if (getSymbol(ctor.locals, name, meaning & SymbolFlags.Value)) {
@@ -667,7 +667,7 @@ namespace ts {
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & SymbolFlags.Type)) {
if (lastLocation && lastLocation.flags & NodeFlags.Static) {
if (lastLocation && getModifierFlags(lastLocation) & ModifierFlags.Static) {
// TypeScript 1.0 spec (April 2014): 3.4.1
// The scope of a type parameter extends over the entire declaration with which the type
// parameter list is associated, with the exception of static member declarations in classes.
@@ -824,7 +824,7 @@ namespace ts {
// No static member is present.
// Check if we're in an instance method and look for a relevant instance member.
if (location === container && !(location.flags & NodeFlags.Static)) {
if (location === container && !(getModifierFlags(location) & ModifierFlags.Static)) {
const instanceType = (<InterfaceType>getDeclaredTypeOfSymbol(classSymbol)).thisType;
if (getPropertyOfType(instanceType, name)) {
error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
@@ -1617,7 +1617,7 @@ namespace ts {
const anyImportSyntax = getAnyImportSyntax(declaration);
if (anyImportSyntax &&
!(anyImportSyntax.flags & NodeFlags.Export) && // import clause without export
!(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export
isDeclarationVisible(<Declaration>anyImportSyntax.parent)) {
getNodeLinks(declaration).isVisible = true;
if (aliasesToMakeVisible) {
@@ -2014,7 +2014,7 @@ namespace ts {
function shouldWriteTypeOfFunctionSymbol() {
const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method
forEach(symbol.declarations, declaration => declaration.flags & NodeFlags.Static));
forEach(symbol.declarations, declaration => getModifierFlags(declaration) & ModifierFlags.Static));
const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) &&
(symbol.parent || // is exported function symbol
forEach(symbol.declarations, declaration =>
@@ -2306,7 +2306,7 @@ namespace ts {
}
const parent = getDeclarationContainer(node);
// If the node is not exported or it is not ambient module element (except import declaration)
if (!(getCombinedNodeFlags(node) & NodeFlags.Export) &&
if (!(getCombinedModifierFlags(node) & ModifierFlags.Export) &&
!(node.kind !== SyntaxKind.ImportEqualsDeclaration && parent.kind !== SyntaxKind.SourceFile && isInAmbientContext(parent))) {
return isGlobalSourceFile(parent);
}
@@ -2319,7 +2319,7 @@ namespace ts {
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
if (node.flags & (NodeFlags.Private | NodeFlags.Protected)) {
if (getModifierFlags(node) & (ModifierFlags.Private | ModifierFlags.Protected)) {
// Private/protected properties/methods are not visible
return false;
}
@@ -3867,7 +3867,7 @@ namespace ts {
const type = getApparentType(current);
if (type !== unknownType) {
const prop = getPropertyOfType(type, name);
if (prop && !(getDeclarationFlagsFromSymbol(prop) & (NodeFlags.Private | NodeFlags.Protected))) {
if (prop && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))) {
commonFlags &= prop.flags;
if (!props) {
props = [prop];
@@ -4309,7 +4309,7 @@ namespace ts {
const declaration = getIndexDeclarationOfSymbol(symbol, kind);
if (declaration) {
return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType,
(declaration.flags & NodeFlags.Readonly) !== 0, declaration);
(getModifierFlags(declaration) & ModifierFlags.Readonly) !== 0, declaration);
}
return undefined;
}
@@ -4845,8 +4845,8 @@ namespace ts {
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
const parent = container && container.parent;
if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) {
if (!(container.flags & NodeFlags.Static) &&
(container.kind !== SyntaxKind.Constructor || isNodeDescendentOf(node, (<ConstructorDeclaration>container).body))) {
if (!(getModifierFlags(container) & ModifierFlags.Static) &&
(container.kind !== SyntaxKind.Constructor || isNodeDescendantOf(node, (<ConstructorDeclaration>container).body))) {
return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
}
}
@@ -4934,7 +4934,7 @@ namespace ts {
case SyntaxKind.JSDocRecordType:
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
// This function assumes that an identifier or qualified name is a type expression
// Callers should first ensure this by calling isTypeNode
// Callers should first ensure this by calling isPartOfTypeNode
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
const symbol = getSymbolAtLocation(node);
@@ -5791,24 +5791,24 @@ namespace ts {
}
}
else if (!(targetProp.flags & SymbolFlags.Prototype)) {
const sourcePropFlags = getDeclarationFlagsFromSymbol(sourceProp);
const targetPropFlags = getDeclarationFlagsFromSymbol(targetProp);
if (sourcePropFlags & NodeFlags.Private || targetPropFlags & NodeFlags.Private) {
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) {
if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
if (reportErrors) {
if (sourcePropFlags & NodeFlags.Private && targetPropFlags & NodeFlags.Private) {
if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) {
reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
}
else {
reportError(Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp),
typeToString(sourcePropFlags & NodeFlags.Private ? source : target),
typeToString(sourcePropFlags & NodeFlags.Private ? target : source));
typeToString(sourcePropFlags & ModifierFlags.Private ? source : target),
typeToString(sourcePropFlags & ModifierFlags.Private ? target : source));
}
}
return Ternary.False;
}
}
else if (targetPropFlags & NodeFlags.Protected) {
else if (targetPropFlags & ModifierFlags.Protected) {
const sourceDeclaredInClass = sourceProp.parent && sourceProp.parent.flags & SymbolFlags.Class;
const sourceClass = sourceDeclaredInClass ? <InterfaceType>getDeclaredTypeOfSymbol(getParentOfSymbol(sourceProp)) : undefined;
const targetClass = <InterfaceType>getDeclaredTypeOfSymbol(getParentOfSymbol(targetProp));
@@ -5820,7 +5820,7 @@ namespace ts {
return Ternary.False;
}
}
else if (sourcePropFlags & NodeFlags.Protected) {
else if (sourcePropFlags & ModifierFlags.Protected) {
if (reportErrors) {
reportError(Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2,
symbolToString(targetProp), typeToString(source), typeToString(target));
@@ -6060,7 +6060,7 @@ namespace ts {
const symbol = type.symbol;
if (symbol && symbol.flags & SymbolFlags.Class) {
const declaration = getClassLikeDeclarationOfSymbol(symbol);
if (declaration && declaration.flags & NodeFlags.Abstract) {
if (declaration && getModifierFlags(declaration) & ModifierFlags.Abstract) {
return true;
}
}
@@ -6100,8 +6100,8 @@ namespace ts {
if (sourceProp === targetProp) {
return Ternary.True;
}
const sourcePropAccessibility = getDeclarationFlagsFromSymbol(sourceProp) & (NodeFlags.Private | NodeFlags.Protected);
const targetPropAccessibility = getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private | NodeFlags.Protected);
const sourcePropAccessibility = getDeclarationModifierFlagsFromSymbol(sourceProp) & ModifierFlags.NonPublicAccessibilityModifier;
const targetPropAccessibility = getDeclarationModifierFlagsFromSymbol(targetProp) & ModifierFlags.NonPublicAccessibilityModifier;
if (sourcePropAccessibility !== targetPropAccessibility) {
return Ternary.False;
}
@@ -7206,8 +7206,8 @@ namespace ts {
let container = getContainingClass(node);
while (container !== undefined) {
if (container === localOrExportSymbol.valueDeclaration && container.name !== node) {
getNodeLinks(container).flags |= NodeCheckFlags.ClassWithBodyScopedClassBinding;
getNodeLinks(node).flags |= NodeCheckFlags.BodyScopedClassBinding;
getNodeLinks(container).flags |= NodeCheckFlags.DecoratedClassWithSelfReference;
getNodeLinks(node).flags |= NodeCheckFlags.SelfReferenceInDecoratedClass;
break;
}
@@ -7323,7 +7323,7 @@ namespace ts {
break;
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
if (container.flags & NodeFlags.Static) {
if (getModifierFlags(container) & ModifierFlags.Static) {
error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
// do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
}
@@ -7339,7 +7339,7 @@ namespace ts {
if (isClassLike(container.parent)) {
const symbol = getSymbolOfNode(container.parent);
return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
return getModifierFlags(container) & ModifierFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
}
if (isInJavaScriptFile(node)) {
@@ -7429,7 +7429,7 @@ namespace ts {
return unknownType;
}
if ((container.flags & NodeFlags.Static) || isCallExpression) {
if ((getModifierFlags(container) & ModifierFlags.Static) || isCallExpression) {
nodeCheckFlag = NodeCheckFlags.SuperStatic;
}
else {
@@ -7494,8 +7494,8 @@ namespace ts {
// This helper creates an object with a "value" property that wraps the `super` property or indexed access for both get and set.
// This is required for destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment
// while a property access can.
if (container.kind === SyntaxKind.MethodDeclaration && container.flags & NodeFlags.Async) {
if (isSuperPropertyOrElementAccess(node.parent) && isAssignmentTarget(node.parent)) {
if (container.kind === SyntaxKind.MethodDeclaration && getModifierFlags(container) & ModifierFlags.Async) {
if (isSuperProperty(node.parent) && isAssignmentTarget(node.parent)) {
getNodeLinks(container).flags |= NodeCheckFlags.AsyncMethodWithSuperBinding;
}
else {
@@ -7560,7 +7560,7 @@ namespace ts {
// topmost container must be something that is directly nested in the class declaration\object literal expression
if (isClassLike(container.parent) || container.parent.kind === SyntaxKind.ObjectLiteralExpression) {
if (container.flags & NodeFlags.Static) {
if (getModifierFlags(container) & ModifierFlags.Static) {
return container.kind === SyntaxKind.MethodDeclaration ||
container.kind === SyntaxKind.MethodSignature ||
container.kind === SyntaxKind.GetAccessor ||
@@ -8785,8 +8785,12 @@ namespace ts {
return s.valueDeclaration ? s.valueDeclaration.kind : SyntaxKind.PropertyDeclaration;
}
function getDeclarationFlagsFromSymbol(s: Symbol): NodeFlags {
return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : s.flags & SymbolFlags.Prototype ? NodeFlags.Public | NodeFlags.Static : 0;
function getDeclarationModifierFlagsFromSymbol(s: Symbol): ModifierFlags {
return s.valueDeclaration ? getCombinedModifierFlags(s.valueDeclaration) : s.flags & SymbolFlags.Prototype ? ModifierFlags.Public | ModifierFlags.Static : 0;
}
function getDeclarationNodeFlagsFromSymbol(s: Symbol): NodeFlags {
return s.valueDeclaration ? getCombinedNodeFlags(s.valueDeclaration) : 0;
}
/**
@@ -8798,7 +8802,7 @@ namespace ts {
* @param prop The symbol for the right hand side of the property access.
*/
function checkClassPropertyAccess(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, type: Type, prop: Symbol): boolean {
const flags = getDeclarationFlagsFromSymbol(prop);
const flags = getDeclarationModifierFlagsFromSymbol(prop);
const declaringClass = <InterfaceType>getDeclaredTypeOfSymbol(getParentOfSymbol(prop));
if (left.kind === SyntaxKind.SuperKeyword) {
@@ -8821,7 +8825,7 @@ namespace ts {
return false;
}
if (flags & NodeFlags.Abstract) {
if (flags & ModifierFlags.Abstract) {
// A method cannot be accessed in a super property access if the method is abstract.
// This error could mask a private property access error. But, a member
// cannot simultaneously be private and abstract, so this will trigger an
@@ -8833,7 +8837,7 @@ namespace ts {
}
// Public properties are otherwise accessible.
if (!(flags & (NodeFlags.Private | NodeFlags.Protected))) {
if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) {
return true;
}
@@ -8844,7 +8848,7 @@ namespace ts {
const enclosingClass = enclosingClassDeclaration ? <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;
// Private property is accessible if declaring and enclosing class are the same
if (flags & NodeFlags.Private) {
if (flags & ModifierFlags.Private) {
if (declaringClass !== enclosingClass) {
error(node, Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass));
return false;
@@ -8864,7 +8868,7 @@ namespace ts {
return false;
}
// No further restrictions for static properties
if (flags & NodeFlags.Static) {
if (flags & ModifierFlags.Static) {
return true;
}
// An instance property must be accessed through an instance of the enclosing class
@@ -10082,7 +10086,7 @@ namespace ts {
// In the case of a merged class-module or class-interface declaration,
// only the class declaration node will have the Abstract flag set.
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
if (valueDecl && valueDecl.flags & NodeFlags.Abstract) {
if (valueDecl && getModifierFlags(valueDecl) & ModifierFlags.Abstract) {
error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(valueDecl.name));
return resolveErrorCall(node);
}
@@ -10700,8 +10704,8 @@ namespace ts {
// Variables declared with 'const'
// Get accessors without matching set accessors
// Enum members
return symbol.flags & SymbolFlags.Property && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Readonly) !== 0 ||
symbol.flags & SymbolFlags.Variable && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 ||
return symbol.flags & SymbolFlags.Property && (getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.Readonly) !== 0 ||
symbol.flags & SymbolFlags.Variable && (getDeclarationNodeFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 ||
symbol.flags & SymbolFlags.Accessor && !(symbol.flags & SymbolFlags.SetAccessor) ||
(symbol.flags & SymbolFlags.EnumMember) !== 0;
}
@@ -11516,7 +11520,7 @@ namespace ts {
checkVariableLikeDeclaration(node);
let func = getContainingFunction(node);
if (node.flags & NodeFlags.AccessibilityModifier) {
if (getModifierFlags(node) & ModifierFlags.AccessibilityModifier) {
func = getContainingFunction(node);
if (!(func.kind === SyntaxKind.Constructor && nodeIsPresent(func.body))) {
error(node, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
@@ -11760,7 +11764,7 @@ namespace ts {
// Abstract methods cannot have an implementation.
// Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
if (node.flags & NodeFlags.Abstract && node.body) {
if (getModifierFlags(node) & ModifierFlags.Abstract && node.body) {
error(node, Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, declarationNameToString(node.name));
}
}
@@ -11822,7 +11826,7 @@ namespace ts {
function isInstancePropertyWithInitializer(n: Node): boolean {
return n.kind === SyntaxKind.PropertyDeclaration &&
!(n.flags & NodeFlags.Static) &&
!(getModifierFlags(n) & ModifierFlags.Static) &&
!!(<PropertyDeclaration>n).initializer;
}
@@ -11847,7 +11851,7 @@ namespace ts {
// or the containing class declares instance member variables with initializers.
const superCallShouldBeFirst =
forEach((<ClassDeclaration>node.parent).members, isInstancePropertyWithInitializer) ||
forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected));
forEach(node.parameters, p => getModifierFlags(p) & ModifierFlags.AccessibilityModifier);
// Skip past any prologue directives to find the first statement
// to ensure that it was a super call.
@@ -11905,7 +11909,7 @@ namespace ts {
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
const otherAccessor = <AccessorDeclaration>getDeclarationOfKind(node.symbol, otherKind);
if (otherAccessor) {
if (((node.flags & NodeFlags.AccessibilityModifier) !== (otherAccessor.flags & NodeFlags.AccessibilityModifier))) {
if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) {
error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
}
@@ -12006,11 +12010,11 @@ namespace ts {
}
function isPrivateWithinAmbient(node: Node): boolean {
return (node.flags & NodeFlags.Private) && isInAmbientContext(node);
return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node);
}
function getEffectiveDeclarationFlags(n: Node, flagsToCheck: NodeFlags): NodeFlags {
let flags = getCombinedNodeFlags(n);
function getEffectiveDeclarationFlags(n: Node, flagsToCheck: ModifierFlags): ModifierFlags {
let flags = getCombinedModifierFlags(n);
// children of classes (even ambient classes) should not be marked as ambient or export
// because those flags have no useful semantics there.
@@ -12018,11 +12022,11 @@ namespace ts {
n.parent.kind !== SyntaxKind.ClassDeclaration &&
n.parent.kind !== SyntaxKind.ClassExpression &&
isInAmbientContext(n)) {
if (!(flags & NodeFlags.Ambient)) {
if (!(flags & ModifierFlags.Ambient)) {
// It is nested in an ambient context, which means it is automatically exported
flags |= NodeFlags.Export;
flags |= ModifierFlags.Export;
}
flags |= NodeFlags.Ambient;
flags |= ModifierFlags.Ambient;
}
return flags & flagsToCheck;
@@ -12043,7 +12047,7 @@ namespace ts {
return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
}
function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, flagsToCheck: NodeFlags, someOverloadFlags: NodeFlags, allOverloadFlags: NodeFlags): void {
function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, flagsToCheck: ModifierFlags, someOverloadFlags: ModifierFlags, allOverloadFlags: ModifierFlags): void {
// Error if some overloads have a flag that is not shared by all overloads. To find the
// deviations, we XOR someOverloadFlags with allOverloadFlags
const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
@@ -12052,16 +12056,16 @@ namespace ts {
forEach(overloads, o => {
const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
if (deviation & NodeFlags.Export) {
if (deviation & ModifierFlags.Export) {
error(o.name, Diagnostics.Overload_signatures_must_all_be_exported_or_not_exported);
}
else if (deviation & NodeFlags.Ambient) {
else if (deviation & ModifierFlags.Ambient) {
error(o.name, Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
}
else if (deviation & (NodeFlags.Private | NodeFlags.Protected)) {
else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) {
error(o.name, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
}
else if (deviation & NodeFlags.Abstract) {
else if (deviation & ModifierFlags.Abstract) {
error(o.name, Diagnostics.Overload_signatures_must_all_be_abstract_or_not_abstract);
}
});
@@ -12080,8 +12084,8 @@ namespace ts {
}
}
const flagsToCheck: NodeFlags = NodeFlags.Export | NodeFlags.Ambient | NodeFlags.Private | NodeFlags.Protected | NodeFlags.Abstract;
let someNodeFlags: NodeFlags = 0;
const flagsToCheck: ModifierFlags = ModifierFlags.Export | ModifierFlags.Ambient | ModifierFlags.Private | ModifierFlags.Protected | ModifierFlags.Abstract;
let someNodeFlags: ModifierFlags = ModifierFlags.None;
let allNodeFlags = flagsToCheck;
let someHaveQuestionToken = false;
let allHaveQuestionToken = true;
@@ -12116,13 +12120,13 @@ namespace ts {
if (node.name && (<FunctionLikeDeclaration>subsequentNode).name && (<Identifier>node.name).text === (<Identifier>(<FunctionLikeDeclaration>subsequentNode).name).text) {
const reportError =
(node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature) &&
(node.flags & NodeFlags.Static) !== (subsequentNode.flags & NodeFlags.Static);
(getModifierFlags(node) & ModifierFlags.Static) !== (getModifierFlags(subsequentNode) & ModifierFlags.Static);
// we can get here in two cases
// 1. mixed static and instance class members
// 2. something with the same name was defined before the set of overloads that prevents them from merging
// here we'll report error only for the first case since for second we should already report error in binder
if (reportError) {
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
const diagnostic = getModifierFlags(node) & ModifierFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
error(errorNode, diagnostic);
}
return;
@@ -12140,7 +12144,7 @@ namespace ts {
else {
// Report different errors regarding non-consecutive blocks of declarations depending on whether
// the node in question is abstract.
if (node.flags & NodeFlags.Abstract) {
if (getModifierFlags(node) & ModifierFlags.Abstract) {
error(errorNode, Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
}
else {
@@ -12219,7 +12223,7 @@ namespace ts {
// Abstract methods can't have an implementation -- in particular, they don't need one.
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract)) {
!(getModifierFlags(lastSeenNonAmbientDeclaration) & ModifierFlags.Abstract)) {
reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
}
@@ -12269,10 +12273,10 @@ namespace ts {
let defaultExportedDeclarationSpaces = SymbolFlags.None;
for (const d of symbol.declarations) {
const declarationSpaces = getDeclarationSpaces(d);
const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, NodeFlags.Export | NodeFlags.Default);
const effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, ModifierFlags.Export | ModifierFlags.Default);
if (effectiveDeclarationFlags & NodeFlags.Export) {
if (effectiveDeclarationFlags & NodeFlags.Default) {
if (effectiveDeclarationFlags & ModifierFlags.Export) {
if (effectiveDeclarationFlags & ModifierFlags.Default) {
defaultExportedDeclarationSpaces |= declarationSpaces;
}
else {
@@ -13012,7 +13016,7 @@ namespace ts {
if (localDeclarationSymbol &&
localDeclarationSymbol !== symbol &&
localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) {
if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) {
const varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList);
const container =
varDeclList.parent.kind === SyntaxKind.VariableStatement && varDeclList.parent.parent
@@ -13788,7 +13792,7 @@ namespace ts {
// Only process instance properties with computed names here.
// Static properties cannot be in conflict with indexers,
// and properties with literal names were already checked.
if (!(member.flags & NodeFlags.Static) && hasDynamicName(member)) {
if (!(getModifierFlags(member) & ModifierFlags.Static) && hasDynamicName(member)) {
const propType = getTypeOfSymbol(member.symbol);
checkIndexConstraintForProperty(member.symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String);
checkIndexConstraintForProperty(member.symbol, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number);
@@ -13899,7 +13903,7 @@ namespace ts {
}
function checkClassDeclaration(node: ClassDeclaration) {
if (!node.name && !(node.flags & NodeFlags.Default)) {
if (!node.name && !(getModifierFlags(node) & ModifierFlags.Default)) {
grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
}
checkClassLikeDeclaration(node);
@@ -14019,7 +14023,7 @@ namespace ts {
}
const derived = getTargetSymbol(getPropertyOfObjectType(type, base.name));
const baseDeclarationFlags = getDeclarationFlagsFromSymbol(base);
const baseDeclarationFlags = getDeclarationModifierFlagsFromSymbol(base);
Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
@@ -14035,7 +14039,7 @@ namespace ts {
// It is an error to inherit an abstract member without implementing it or being declared abstract.
// If there is no declaration for the derived class (as in the case of class expressions),
// then the class cannot be declared abstract.
if (baseDeclarationFlags & NodeFlags.Abstract && (!derivedClassDecl || !(derivedClassDecl.flags & NodeFlags.Abstract))) {
if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !(getModifierFlags(derivedClassDecl) & ModifierFlags.Abstract))) {
if (derivedClassDecl.kind === SyntaxKind.ClassExpression) {
error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1,
symbolToString(baseProperty), typeToString(baseType));
@@ -14048,13 +14052,13 @@ namespace ts {
}
else {
// derived overrides base.
const derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived);
if ((baseDeclarationFlags & NodeFlags.Private) || (derivedDeclarationFlags & NodeFlags.Private)) {
const derivedDeclarationFlags = getDeclarationModifierFlagsFromSymbol(derived);
if ((baseDeclarationFlags & ModifierFlags.Private) || (derivedDeclarationFlags & ModifierFlags.Private)) {
// either base or derived property is private - not override, skip it
continue;
}
if ((baseDeclarationFlags & NodeFlags.Static) !== (derivedDeclarationFlags & NodeFlags.Static)) {
if ((baseDeclarationFlags & ModifierFlags.Static) !== (derivedDeclarationFlags & ModifierFlags.Static)) {
// value of 'static' is not the same for properties - not override, skip it
continue;
}
@@ -14727,7 +14731,7 @@ namespace ts {
// If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
return;
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) {
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
}
if (checkExternalImportOrExportDeclaration(node)) {
@@ -14757,7 +14761,7 @@ namespace ts {
checkGrammarDecorators(node) || checkGrammarModifiers(node);
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
checkImportBinding(node);
if (node.flags & NodeFlags.Export) {
if (getModifierFlags(node) & ModifierFlags.Export) {
markExportAsReferenced(node);
}
if (isInternalModuleImportEqualsDeclaration(node)) {
@@ -14790,7 +14794,7 @@ namespace ts {
return;
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) {
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
}
@@ -14849,7 +14853,7 @@ namespace ts {
return;
}
// Grammar checking
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && getModifierFlags(node) !== 0) {
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
}
if (node.expression.kind === SyntaxKind.Identifier) {
@@ -15177,7 +15181,7 @@ namespace ts {
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
const symbols: SymbolTable = {};
let memberFlags: NodeFlags = 0;
let memberFlags: ModifierFlags = ModifierFlags.None;
if (isInsideWithStatementBody(location)) {
// We cannot answer semantic questions within a with block, do not proceed any further
@@ -15218,7 +15222,7 @@ namespace ts {
// add the type parameters into the symbol table
// (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
// Note: that the memberFlags come from previous iteration.
if (!(memberFlags & NodeFlags.Static)) {
if (!(memberFlags & ModifierFlags.Static)) {
copySymbols(getSymbolOfNode(location).members, meaning & SymbolFlags.Type);
}
break;
@@ -15234,7 +15238,7 @@ namespace ts {
copySymbol(argumentsSymbol, meaning);
}
memberFlags = location.flags;
memberFlags = getModifierFlags(location);
location = location.parent;
}
@@ -15385,7 +15389,7 @@ namespace ts {
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
}
else if (isExpression(entityName)) {
else if (isPartOfExpression(entityName)) {
if (nodeIsMissing(entityName)) {
// Missing entity name.
return undefined;
@@ -15468,7 +15472,7 @@ namespace ts {
case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword:
const type = isExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
const type = isPartOfExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
return type.symbol;
case SyntaxKind.ThisType:
@@ -15529,11 +15533,11 @@ namespace ts {
return unknownType;
}
if (isTypeNode(node)) {
if (isPartOfTypeNode(node)) {
return getTypeFromTypeNode(<TypeNode>node);
}
if (isExpression(node)) {
if (isPartOfExpression(node)) {
return getTypeOfExpression(<Expression>node);
}
@@ -15592,7 +15596,7 @@ namespace ts {
*/
function getParentTypeOfClassElement(node: ClassElement) {
const classSymbol = getSymbolOfNode(node.parent);
return node.flags & NodeFlags.Static
return getModifierFlags(node) & ModifierFlags.Static
? getTypeOfSymbol(classSymbol)
: getDeclaredTypeOfSymbol(classSymbol);
}
@@ -16169,7 +16173,7 @@ namespace ts {
}
let lastStatic: Node, lastPrivate: Node, lastProtected: Node, lastDeclare: Node, lastAsync: Node, lastReadonly: Node;
let flags = 0;
let flags = ModifierFlags.None;
for (const modifier of node.modifiers) {
if (modifier.kind !== SyntaxKind.ReadonlyKeyword) {
if (node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature) {
@@ -16201,22 +16205,22 @@ namespace ts {
lastPrivate = modifier;
}
if (flags & NodeFlags.AccessibilityModifier) {
if (flags & ModifierFlags.AccessibilityModifier) {
return grammarErrorOnNode(modifier, Diagnostics.Accessibility_modifier_already_seen);
}
else if (flags & NodeFlags.Static) {
else if (flags & ModifierFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
}
else if (flags & NodeFlags.Readonly) {
else if (flags & ModifierFlags.Readonly) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
}
else if (flags & NodeFlags.Async) {
else if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
}
else if (flags & NodeFlags.Abstract) {
else if (flags & ModifierFlags.Abstract) {
if (modifier.kind === SyntaxKind.PrivateKeyword) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
}
@@ -16228,13 +16232,13 @@ namespace ts {
break;
case SyntaxKind.StaticKeyword:
if (flags & NodeFlags.Static) {
if (flags & ModifierFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static");
}
else if (flags & NodeFlags.Readonly) {
else if (flags & ModifierFlags.Readonly) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
}
else if (flags & NodeFlags.Async) {
else if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
@@ -16243,35 +16247,35 @@ namespace ts {
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
}
else if (flags & NodeFlags.Abstract) {
else if (flags & ModifierFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
}
flags |= NodeFlags.Static;
flags |= ModifierFlags.Static;
lastStatic = modifier;
break;
case SyntaxKind.ReadonlyKeyword:
if (flags & NodeFlags.Readonly) {
if (flags & ModifierFlags.Readonly) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "readonly");
}
else if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature && node.kind !== SyntaxKind.IndexSignature) {
return grammarErrorOnNode(modifier, Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
}
flags |= NodeFlags.Readonly;
flags |= ModifierFlags.Readonly;
lastReadonly = modifier;
break;
case SyntaxKind.ExportKeyword:
if (flags & NodeFlags.Export) {
if (flags & ModifierFlags.Export) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "export");
}
else if (flags & NodeFlags.Ambient) {
else if (flags & ModifierFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
}
else if (flags & NodeFlags.Abstract) {
else if (flags & ModifierFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
}
else if (flags & NodeFlags.Async) {
else if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
@@ -16280,14 +16284,14 @@ namespace ts {
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
}
flags |= NodeFlags.Export;
flags |= ModifierFlags.Export;
break;
case SyntaxKind.DeclareKeyword:
if (flags & NodeFlags.Ambient) {
if (flags & ModifierFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare");
}
else if (flags & NodeFlags.Async) {
else if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
@@ -16299,76 +16303,76 @@ namespace ts {
else if (isInAmbientContext(node.parent) && node.parent.kind === SyntaxKind.ModuleBlock) {
return grammarErrorOnNode(modifier, Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
}
flags |= NodeFlags.Ambient;
flags |= ModifierFlags.Ambient;
lastDeclare = modifier;
break;
case SyntaxKind.AbstractKeyword:
if (flags & NodeFlags.Abstract) {
if (flags & ModifierFlags.Abstract) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract");
}
if (node.kind !== SyntaxKind.ClassDeclaration) {
if (node.kind !== SyntaxKind.MethodDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics.abstract_modifier_can_only_appear_on_a_class_or_method_declaration);
}
if (!(node.parent.kind === SyntaxKind.ClassDeclaration && node.parent.flags & NodeFlags.Abstract)) {
if (!(node.parent.kind === SyntaxKind.ClassDeclaration && getModifierFlags(node.parent) & ModifierFlags.Abstract)) {
return grammarErrorOnNode(modifier, Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
}
if (flags & NodeFlags.Static) {
if (flags & ModifierFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
}
if (flags & NodeFlags.Private) {
if (flags & ModifierFlags.Private) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
}
}
flags |= NodeFlags.Abstract;
flags |= ModifierFlags.Abstract;
break;
case SyntaxKind.AsyncKeyword:
if (flags & NodeFlags.Async) {
if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
}
else if (flags & NodeFlags.Ambient || isInAmbientContext(node.parent)) {
else if (flags & ModifierFlags.Ambient || isInAmbientContext(node.parent)) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
}
flags |= NodeFlags.Async;
flags |= ModifierFlags.Async;
lastAsync = modifier;
break;
}
}
if (node.kind === SyntaxKind.Constructor) {
if (flags & NodeFlags.Static) {
if (flags & ModifierFlags.Static) {
return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
}
if (flags & NodeFlags.Abstract) {
if (flags & ModifierFlags.Abstract) {
return grammarErrorOnNode(lastStatic, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract");
}
else if (flags & NodeFlags.Protected) {
else if (flags & ModifierFlags.Protected) {
return grammarErrorOnNode(lastProtected, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "protected");
}
else if (flags & NodeFlags.Private) {
else if (flags & ModifierFlags.Private) {
return grammarErrorOnNode(lastPrivate, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
}
else if (flags & NodeFlags.Async) {
else if (flags & ModifierFlags.Async) {
return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
}
else if (flags & NodeFlags.Readonly) {
else if (flags & ModifierFlags.Readonly) {
return grammarErrorOnNode(lastReadonly, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
}
return;
}
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) {
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & ModifierFlags.Ambient) {
return grammarErrorOnNode(lastDeclare, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
}
else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.AccessibilityModifier) && isBindingPattern((<ParameterDeclaration>node).name)) {
else if (node.kind === SyntaxKind.Parameter && (flags & ModifierFlags.AccessibilityModifier) && isBindingPattern((<ParameterDeclaration>node).name)) {
return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_a_binding_pattern);
}
if (flags & NodeFlags.Async) {
if (flags & ModifierFlags.Async) {
return checkGrammarAsyncModifier(node, lastAsync);
}
}
@@ -16485,7 +16489,7 @@ namespace ts {
if (parameter.dotDotDotToken) {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
}
if (parameter.flags & NodeFlags.Modifier) {
if (getModifierFlags(parameter) !== 0) {
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
}
if (parameter.questionToken) {
@@ -16672,11 +16676,13 @@ namespace ts {
}
// Modifiers are never allowed on properties except for 'async' on a method declaration
forEach(prop.modifiers, mod => {
if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) {
grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod));
if (prop.modifiers) {
for (const mod of prop.modifiers) {
if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) {
grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod));
}
}
});
}
// ECMA-262 11.1.5 Object Initialiser
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
@@ -16830,7 +16836,7 @@ namespace ts {
if (parameter.dotDotDotToken) {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
}
else if (parameter.flags & NodeFlags.Modifier) {
else if (getModifierFlags(parameter) !== 0) {
return grammarErrorOnNode(accessor.name, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
}
else if (parameter.questionToken) {
@@ -17136,8 +17142,7 @@ namespace ts {
node.kind === SyntaxKind.ImportEqualsDeclaration ||
node.kind === SyntaxKind.ExportDeclaration ||
node.kind === SyntaxKind.ExportAssignment ||
(node.flags & NodeFlags.Ambient) ||
(node.flags & (NodeFlags.Export | NodeFlags.Default))) {
getModifierFlags(node) & (ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) {
return false;
}
+7
View File
@@ -320,6 +320,13 @@ namespace ts {
name: "allowSyntheticDefaultImports",
type: "boolean",
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
},
{
// this option will be removed when this is merged with master and exists solely
// to enable the tree transforming emitter side-by-side with the existing emitter.
name: "experimentalTransforms",
type: "boolean",
experimental: true
}
];
+248
View File
@@ -0,0 +1,248 @@
/// <reference path="sourcemap.ts" />
/* @internal */
namespace ts {
export interface CommentWriter {
reset(): void;
setSourceFile(sourceFile: SourceFile): void;
getLeadingComments(range: Node, getAdditionalRange?: (range: Node) => Node): CommentRange[];
getLeadingComments(range: TextRange): CommentRange[];
getLeadingCommentsOfPosition(pos: number): CommentRange[];
getTrailingComments(range: Node, getAdditionalRange?: (range: Node) => Node): CommentRange[];
getTrailingComments(range: TextRange): CommentRange[];
getTrailingCommentsOfPosition(pos: number): CommentRange[];
emitLeadingComments(range: TextRange, comments?: CommentRange[]): void;
emitTrailingComments(range: TextRange, comments?: CommentRange[]): void;
emitDetachedComments(range: TextRange): void;
}
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
const compilerOptions = host.getCompilerOptions();
const newLine = host.getNewLine();
const { emitPos } = sourceMap;
let currentSourceFile: SourceFile;
let currentText: string;
let currentLineMap: number[];
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
// This maps start->end for a comment range. See `hasConsumedCommentRange` and
// `consumeCommentRange` for usage.
let consumedCommentRanges: number[];
let leadingCommentRangePositions: boolean[];
let trailingCommentRangePositions: boolean[];
return compilerOptions.removeComments
? createCommentRemovingWriter()
: createCommentPreservingWriter();
function createCommentRemovingWriter(): CommentWriter {
return {
reset,
setSourceFile,
getLeadingComments(range: TextRange, getAdditionalRange?: (range: TextRange) => TextRange): CommentRange[] { return undefined; },
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
getTrailingComments(range: TextRange, getAdditionalRange?: (range: TextRange) => TextRange): CommentRange[] { return undefined; },
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
emitLeadingComments(range: TextRange, comments?: CommentRange[]): void { },
emitTrailingComments(range: TextRange, comments?: CommentRange[]): void { },
emitDetachedComments,
};
function emitDetachedComments(node: TextRange): void {
emitDetachedCommentsAndUpdateCommentsInfo(node, /*removeComments*/ true);
}
}
function createCommentPreservingWriter(): CommentWriter {
const noComments: CommentRange[] = [];
return {
reset,
setSourceFile,
getLeadingComments,
getLeadingCommentsOfPosition,
getTrailingComments,
getTrailingCommentsOfPosition,
emitLeadingComments,
emitTrailingComments,
emitDetachedComments,
};
function getLeadingComments(range: TextRange | Node, getAdditionalRange?: (range: Node) => Node) {
let comments = getLeadingCommentsOfPosition(range.pos);
if (getAdditionalRange) {
let additionalRange = getAdditionalRange(<Node>range);
while (additionalRange) {
comments = concatenate(
getLeadingCommentsOfPosition(additionalRange.pos),
comments
);
additionalRange = getAdditionalRange(additionalRange);
}
}
return comments;
}
function getTrailingComments(range: TextRange | Node, getAdditionalRange?: (range: Node) => Node) {
let comments = getTrailingCommentsOfPosition(range.end);
if (getAdditionalRange) {
let additionalRange = getAdditionalRange(<Node>range);
while (additionalRange) {
comments = concatenate(
comments,
getTrailingCommentsOfPosition(additionalRange.end)
);
additionalRange = getAdditionalRange(additionalRange);
}
}
return comments;
}
function getLeadingCommentsOfPosition(pos: number) {
if (positionIsSynthesized(pos) || leadingCommentRangePositions[pos]) {
return undefined;
}
leadingCommentRangePositions[pos] = true;
const comments = hasDetachedComments(pos)
? getLeadingCommentsWithoutDetachedComments()
: getLeadingCommentRanges(currentText, pos);
return consumeCommentRanges(comments);
}
function getTrailingCommentsOfPosition(pos: number) {
if (positionIsSynthesized(pos) || trailingCommentRangePositions[pos]) {
return undefined;
}
trailingCommentRangePositions[pos] = true;
const comments = getTrailingCommentRanges(currentText, pos);
return consumeCommentRanges(comments);
}
function emitLeadingComments(range: TextRange, comments = getLeadingComments(range)) {
emitNewLineBeforeLeadingComments(currentLineMap, writer, range, comments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitTrailingComments(range: TextRange, comments = getTrailingComments(range)) {
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
}
function emitDetachedComments(range: TextRange) {
emitDetachedCommentsAndUpdateCommentsInfo(range, /*removeComments*/ false);
}
function hasConsumedCommentRange(comment: CommentRange) {
return comment.end === consumedCommentRanges[comment.pos];
}
function consumeCommentRange(comment: CommentRange) {
if (!hasConsumedCommentRange(comment)) {
consumedCommentRanges[comment.pos] = comment.end;
return true;
}
return false;
}
function consumeCommentRanges(comments: CommentRange[]) {
let consumed: CommentRange[];
if (comments) {
let commentsSkipped = 0;
let commentsConsumed = 0;
for (let i = 0; i < comments.length; i++) {
const comment = comments[i];
if (consumeCommentRange(comment)) {
commentsConsumed++;
if (commentsSkipped !== 0) {
if (consumed === undefined) {
consumed = [comment];
}
else {
consumed.push(comment);
}
}
}
else {
commentsSkipped++;
if (commentsConsumed !== 0 && consumed === undefined) {
consumed = comments.slice(0, i);
}
}
}
if (commentsConsumed) {
return consumed || comments;
}
}
return noComments;
}
}
function reset() {
currentSourceFile = undefined;
currentText = undefined;
currentLineMap = undefined;
detachedCommentsInfo = undefined;
consumedCommentRanges = undefined;
trailingCommentRangePositions = undefined;
leadingCommentRangePositions = undefined;
}
function setSourceFile(sourceFile: SourceFile) {
currentSourceFile = sourceFile;
currentText = sourceFile.text;
currentLineMap = getLineStarts(sourceFile);
detachedCommentsInfo = undefined;
consumedCommentRanges = [];
leadingCommentRangePositions = [];
trailingCommentRangePositions = [];
}
function hasDetachedComments(pos: number) {
return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos;
}
function getLeadingCommentsWithoutDetachedComments() {
// get the leading comments from detachedPos
const pos = lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos;
const leadingComments = getLeadingCommentRanges(currentText, pos);
if (detachedCommentsInfo.length - 1) {
detachedCommentsInfo.pop();
}
else {
detachedCommentsInfo = undefined;
}
return leadingComments;
}
function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange, removeComments: boolean) {
const currentDetachedCommentInfo = emitDetachedComments(currentText, currentLineMap, writer, writeComment, node, newLine, removeComments);
if (currentDetachedCommentInfo) {
if (detachedCommentsInfo) {
detachedCommentsInfo.push(currentDetachedCommentInfo);
}
else {
detachedCommentsInfo = [currentDetachedCommentInfo];
}
}
}
function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string) {
emitPos(comment.pos);
writeCommentRange(text, lineMap, writer, comment, newLine);
emitPos(comment.end);
}
}
}
+231 -34
View File
@@ -91,6 +91,23 @@ namespace ts {
return undefined;
}
/**
* Iterates through `array` by index and performs the callback on each element of array until the callback
* returns a falsey value, then returns false.
* If no such value is found, the callback is applied to each element of array and `true` is returned.
*/
export function every<T>(array: T[], callback: (element: T, index: number) => boolean): boolean {
if (array) {
for (let i = 0, len = array.length; i < len; i++) {
if (!callback(array[i], i)) {
return false;
}
}
}
return true;
}
export function contains<T>(array: T[], value: T): boolean {
if (array) {
for (const v of array) {
@@ -113,11 +130,12 @@ namespace ts {
return -1;
}
export function countWhere<T>(array: T[], predicate: (x: T) => boolean): number {
export function countWhere<T>(array: T[], predicate: (x: T, i: number) => boolean): number {
let count = 0;
if (array) {
for (const v of array) {
if (predicate(v)) {
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (predicate(v, i)) {
count++;
}
}
@@ -125,35 +143,151 @@ namespace ts {
return count;
}
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
export function filter<T, U extends T>(array: T[], f: (x: T, i: number) => x is U): U[];
export function filter<T>(array: T[], f: (x: T, i: number) => boolean): T[];
export function filter<T>(array: T[], f: (x: T, i: number) => boolean): T[] {
let result: T[];
if (array) {
result = [];
for (const item of array) {
if (f(item)) {
result.push(item);
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (f(v, i)) {
result.push(v);
}
}
}
return result;
}
export function map<T, U>(array: T[], f: (x: T) => U): U[] {
export function map<T, U>(array: T[], f: (x: T, i: number) => U): U[] {
let result: U[];
if (array) {
result = [];
for (const v of array) {
result.push(f(v));
for (let i = 0; i < array.length; i++) {
const v = array[i];
result.push(f(v, i));
}
}
return result;
}
/**
* Flattens an array containing a mix of array or non-array elements.
*
* @param array The array to flatten.
*/
export function flatten<T>(array: (T | T[])[]): T[] {
let result: T[];
if (array) {
result = [];
for (const v of array) {
if (v) {
if (isArray(v)) {
addRange(result, v);
}
else {
result.push(v);
}
}
}
}
return result;
}
/**
* Maps an array. If the mapped value is an array, it is spread into the result.
*
* @param array The array to map.
* @param mapfn The callback used to map the result into one or more values.
*/
export function flatMap<T, U>(array: T[], mapfn: (x: T, i: number) => U | U[]): U[] {
let result: U[];
if (array) {
result = [];
for (let i = 0; i < array.length; i++) {
const v = mapfn(array[i], i);
if (v) {
if (isArray(v)) {
addRange(result, v);
}
else {
result.push(v);
}
}
}
}
return result;
}
/**
* Computes the first matching span of elements and returns a tuple of the first span
* and the remaining elements.
*/
export function span<T>(array: T[], f: (x: T, i: number) => boolean): [T[], T[]] {
if (array) {
for (let i = 0; i < array.length; i++) {
if (!f(array[i], i)) {
return [array.slice(0, i), array.slice(i)];
}
}
return [array.slice(0), []];
}
return undefined;
}
/**
* Maps contiguous spans of values with the same key.
*
* @param array The array to map.
* @param keyfn A callback used to select the key for an element.
* @param mapfn A callback used to map a contiguous chunk of values to a single value.
*/
export function spanMap<T, K, U>(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K) => U): U[] {
let result: U[];
if (array) {
result = [];
const len = array.length;
let previousKey: K;
let key: K;
let start = 0;
let pos = 0;
while (start < len) {
while (pos < len) {
const value = array[pos];
key = keyfn(value, pos);
if (pos === 0) {
previousKey = key;
}
else if (key !== previousKey) {
break;
}
pos++;
}
if (start < pos) {
const v = mapfn(array.slice(start, pos), previousKey);
if (v) {
result.push(v);
}
start = pos;
}
previousKey = key;
pos++;
}
}
return result;
}
export function concatenate<T>(array1: T[], array2: T[]): T[] {
if (!array2 || !array2.length) return array1;
if (!array1 || !array1.length) return array2;
return array1.concat(array2);
return [...array1, ...array2];
}
export function deduplicate<T>(array: T[]): T[] {
@@ -169,6 +303,27 @@ namespace ts {
return result;
}
/**
* Compacts an array, removing any falsey elements.
*/
export function compact<T>(array: T[]): T[] {
let result: T[];
if (array) {
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (result || !v) {
if (!result) {
result = array.slice(0, i);
}
if (v) {
result.push(v);
}
}
}
}
return result || array;
}
export function sum(array: any[], prop: string): number {
let result = 0;
for (const v of array) {
@@ -195,15 +350,25 @@ namespace ts {
return true;
}
export function firstOrUndefined<T>(array: T[]): T {
return array && array.length > 0
? array[0]
: undefined;
}
export function singleOrUndefined<T>(array: T[]): T {
return array && array.length === 1
? array[0]
: undefined;
}
/**
* Returns the last element of an array if non-empty, undefined otherwise.
*/
export function lastOrUndefined<T>(array: T[]): T {
if (array.length === 0) {
return undefined;
}
return array[array.length - 1];
return array && array.length > 0
? array[array.length - 1]
: undefined;
}
/**
@@ -235,38 +400,50 @@ namespace ts {
return ~low;
}
export function reduceLeft<T>(array: T[], f: (a: T, x: T) => T): T;
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
export function reduceLeft<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U): U;
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T): T {
if (array) {
const count = array.length;
if (count > 0) {
let pos = 0;
let result = arguments.length <= 2 ? array[pos] : initial;
pos++;
while (pos < count) {
result = f(<U>result, array[pos]);
let result: T;
if (arguments.length <= 2) {
result = array[pos];
pos++;
}
return <U>result;
else {
result = initial;
}
while (pos < count) {
result = f(result, array[pos], pos);
pos++;
}
return result;
}
}
return initial;
}
export function reduceRight<T>(array: T[], f: (a: T, x: T) => T): T;
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
export function reduceRight<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U): U;
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T): T {
if (array) {
let pos = array.length - 1;
if (pos >= 0) {
let result = arguments.length <= 2 ? array[pos] : initial;
pos--;
while (pos >= 0) {
result = f(<U>result, array[pos]);
let result: T;
if (arguments.length <= 2) {
result = array[pos];
pos--;
}
return <U>result;
else {
result = initial;
}
while (pos >= 0) {
result = f(result, array[pos], pos);
pos--;
}
return result;
}
}
return initial;
@@ -836,7 +1013,11 @@ namespace ts {
this.pos = pos;
this.end = end;
this.flags = NodeFlags.None;
this.modifierFlagsCache = ModifierFlags.None;
this.transformFlags = TransformFlags.None;
this.excludeTransformFlags = TransformFlags.None;
this.parent = undefined;
this.original = undefined;
}
export let objectAllocator: ObjectAllocator = {
@@ -855,7 +1036,12 @@ namespace ts {
}
export namespace Debug {
const currentAssertionLevel = AssertionLevel.None;
declare var process: any;
declare var require: any;
const currentAssertionLevel = getDevelopmentMode() === "development"
? AssertionLevel.Normal
: AssertionLevel.None;
export function shouldAssert(level: AssertionLevel): boolean {
return currentAssertionLevel >= level;
@@ -875,6 +1061,17 @@ namespace ts {
export function fail(message?: string): void {
Debug.assert(/*expression*/ false, message);
}
function getDevelopmentMode() {
return typeof require !== "undefined"
&& typeof process !== "undefined"
&& !process.browser
&& process.nextTick
&& process.env
&& process.env.NODE_ENV
? String(process.env.NODE_ENV).toLowerCase()
: undefined;
}
}
export function copyListRemovingItem<T>(item: T, list: T[]) {
+33 -32
View File
@@ -91,7 +91,7 @@ namespace ts {
// Emit reference in dts, if the file reference was not already emitted
if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) {
// Add a reference to generated dts file,
// global file reference is added only
// global file reference is added only
// - if it is not bundled emit (because otherwise it would be self reference)
// - and it is not already added
if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) {
@@ -144,7 +144,7 @@ namespace ts {
if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
// if file was external module with augmentations - this fact should be preserved in .d.ts as well.
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
// that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
write("export {};");
writeLine();
@@ -349,7 +349,7 @@ namespace ts {
const jsDocComments = getJsDocCommentsFromText(declaration, currentText);
emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, writeCommentRange);
emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeCommentRange);
}
}
@@ -623,12 +623,13 @@ namespace ts {
function emitModuleElementDeclarationFlags(node: Node) {
// If the node is parented in the current source file we need to emit export declare or just export
if (node.parent.kind === SyntaxKind.SourceFile) {
const modifiers = getModifierFlags(node);
// If the node is exported
if (node.flags & NodeFlags.Export) {
if (modifiers & ModifierFlags.Export) {
write("export ");
}
if (node.flags & NodeFlags.Default) {
if (modifiers & ModifierFlags.Default) {
write("default ");
}
else if (node.kind !== SyntaxKind.InterfaceDeclaration && !noDeclare) {
@@ -637,21 +638,21 @@ namespace ts {
}
}
function emitClassMemberDeclarationFlags(flags: NodeFlags) {
if (flags & NodeFlags.Private) {
function emitClassMemberDeclarationFlags(flags: ModifierFlags) {
if (flags & ModifierFlags.Private) {
write("private ");
}
else if (flags & NodeFlags.Protected) {
else if (flags & ModifierFlags.Protected) {
write("protected ");
}
if (flags & NodeFlags.Static) {
if (flags & ModifierFlags.Static) {
write("static ");
}
if (flags & NodeFlags.Readonly) {
if (flags & ModifierFlags.Readonly) {
write("readonly ");
}
if (flags & NodeFlags.Abstract) {
if (flags & ModifierFlags.Abstract) {
write("abstract ");
}
}
@@ -660,7 +661,7 @@ namespace ts {
// note usage of writer. methods instead of aliases created, just to make sure we are using
// correct writer especially to handle asynchronous alias writing
emitJsDocComments(node);
if (node.flags & NodeFlags.Export) {
if (hasModifier(node, ModifierFlags.Export)) {
write("export ");
}
write("import ");
@@ -698,12 +699,12 @@ namespace ts {
}
function writeImportDeclaration(node: ImportDeclaration) {
if (!node.importClause && !(node.flags & NodeFlags.Export)) {
if (!node.importClause && !hasModifier(node, ModifierFlags.Export)) {
// do not write non-exported import declarations that don't have import clauses
return;
}
emitJsDocComments(node);
if (node.flags & NodeFlags.Export) {
if (hasModifier(node, ModifierFlags.Export)) {
write("export ");
}
write("import ");
@@ -736,7 +737,7 @@ namespace ts {
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) {
// emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
// external modules since they are indistingushable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
// so compiler will treat them as external modules.
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration;
@@ -893,7 +894,7 @@ namespace ts {
}
function isPrivateMethodTypeParameter(node: TypeParameterDeclaration) {
return node.parent.kind === SyntaxKind.MethodDeclaration && (node.parent.flags & NodeFlags.Private);
return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private);
}
function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) {
@@ -943,7 +944,7 @@ namespace ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
if (node.parent.flags & NodeFlags.Static) {
if (hasModifier(node.parent, ModifierFlags.Static)) {
diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
}
else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
@@ -1018,7 +1019,7 @@ namespace ts {
function emitParameterProperties(constructorDeclaration: ConstructorDeclaration) {
if (constructorDeclaration) {
forEach(constructorDeclaration.parameters, param => {
if (param.flags & NodeFlags.AccessibilityModifier) {
if (hasModifier(param, ModifierFlags.AccessibilityModifier)) {
emitPropertyDeclaration(param);
}
});
@@ -1027,7 +1028,7 @@ namespace ts {
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
if (node.flags & NodeFlags.Abstract) {
if (hasModifier(node, ModifierFlags.Abstract)) {
write("abstract ");
}
@@ -1077,7 +1078,7 @@ namespace ts {
}
emitJsDocComments(node);
emitClassMemberDeclarationFlags(node.flags);
emitClassMemberDeclarationFlags(getModifierFlags(node));
emitVariableDeclaration(<VariableDeclaration>node);
write(";");
writeLine();
@@ -1102,7 +1103,7 @@ namespace ts {
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
emitTypeOfVariableDeclarationFromTypeLiteral(node);
}
else if (!(node.flags & NodeFlags.Private)) {
else if (!hasModifier(node, ModifierFlags.Private)) {
writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError);
}
}
@@ -1119,7 +1120,7 @@ namespace ts {
// This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) {
// TODO(jfreeman): Deal with computed properties in error reporting.
if (node.flags & NodeFlags.Static) {
if (hasModifier(node, ModifierFlags.Static)) {
return symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
@@ -1230,9 +1231,9 @@ namespace ts {
if (node === accessors.firstAccessor) {
emitJsDocComments(accessors.getAccessor);
emitJsDocComments(accessors.setAccessor);
emitClassMemberDeclarationFlags(node.flags | (accessors.setAccessor ? 0 : NodeFlags.Readonly));
emitClassMemberDeclarationFlags(getModifierFlags(node) | (accessors.setAccessor ? 0 : ModifierFlags.Readonly));
writeTextOfNode(currentText, node.name);
if (!(node.flags & NodeFlags.Private)) {
if (!hasModifier(node, ModifierFlags.Private)) {
accessorWithTypeAnnotation = node;
let type = getTypeAnnotationFromAccessor(node);
if (!type) {
@@ -1263,7 +1264,7 @@ namespace ts {
let diagnosticMessage: DiagnosticMessage;
if (accessorWithTypeAnnotation.kind === SyntaxKind.SetAccessor) {
// Setters have to have type named and cannot infer it so, the type should always be named
if (accessorWithTypeAnnotation.parent.flags & NodeFlags.Static) {
if (hasModifier(accessorWithTypeAnnotation.parent, ModifierFlags.Static)) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1;
@@ -1281,7 +1282,7 @@ namespace ts {
};
}
else {
if (accessorWithTypeAnnotation.flags & NodeFlags.Static) {
if (hasModifier(accessorWithTypeAnnotation, ModifierFlags.Static)) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
@@ -1317,7 +1318,7 @@ namespace ts {
emitModuleElementDeclarationFlags(node);
}
else if (node.kind === SyntaxKind.MethodDeclaration) {
emitClassMemberDeclarationFlags(node.flags);
emitClassMemberDeclarationFlags(getModifierFlags(node));
}
if (node.kind === SyntaxKind.FunctionDeclaration) {
write("function ");
@@ -1347,7 +1348,7 @@ namespace ts {
if (node.kind === SyntaxKind.IndexSignature) {
// Index signature can have readonly modifier
emitClassMemberDeclarationFlags(node.flags);
emitClassMemberDeclarationFlags(getModifierFlags(node));
write("[");
}
else {
@@ -1378,7 +1379,7 @@ namespace ts {
emitType(node.type);
}
}
else if (node.kind !== SyntaxKind.Constructor && !(node.flags & NodeFlags.Private)) {
else if (node.kind !== SyntaxKind.Constructor && !hasModifier(node, ModifierFlags.Private)) {
writeReturnTypeAtSignature(node, getReturnTypeVisibilityError);
}
@@ -1415,7 +1416,7 @@ namespace ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
if (node.flags & NodeFlags.Static) {
if (hasModifier(node, ModifierFlags.Static)) {
diagnosticMessage = symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
@@ -1481,7 +1482,7 @@ namespace ts {
node.parent.parent.kind === SyntaxKind.TypeLiteral) {
emitTypeOfVariableDeclarationFromTypeLiteral(node);
}
else if (!(node.parent.flags & NodeFlags.Private)) {
else if (!hasModifier(node.parent, ModifierFlags.Private)) {
writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError);
}
@@ -1517,7 +1518,7 @@ namespace ts {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
if (node.parent.flags & NodeFlags.Static) {
if (hasModifier(node.parent, ModifierFlags.Static)) {
return symbolAccesibilityResult.errorModuleName ?
symbolAccesibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
+95 -100
View File
@@ -346,7 +346,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
function isUniqueLocalName(name: string, container: Node): boolean {
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
if (node.locals && hasProperty(node.locals, name)) {
// We conservatively include alias symbols to cover cases where they're emitted as locals
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
@@ -895,7 +895,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
function emitLiteral(node: LiteralExpression | TemplateLiteralFragment) {
const text = getLiteralText(node);
const text = getLiteralText(node, currentSourceFile, languageVersion);
if ((compilerOptions.sourceMap || compilerOptions.inlineSourceMap) && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
writer.writeLiteral(text);
@@ -909,43 +909,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
}
function getLiteralText(node: LiteralExpression | TemplateLiteralFragment) {
// Any template literal or string literal with an extended escape
// (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
if (languageVersion < ScriptTarget.ES6 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
return getQuotedEscapedLiteralText("\"", node.text, "\"");
}
// If we don't need to downlevel and we can reach the original source text using
// the node's parent reference, then simply get the text as it was originally written.
if (node.parent) {
return getTextOfNodeFromSourceText(currentText, node);
}
// If we can't reach the original source text, use the canonical form if it's a number,
// or an escaped quoted form of the original text if it's string-like.
switch (node.kind) {
case SyntaxKind.StringLiteral:
return getQuotedEscapedLiteralText("\"", node.text, "\"");
case SyntaxKind.NoSubstitutionTemplateLiteral:
return getQuotedEscapedLiteralText("`", node.text, "`");
case SyntaxKind.TemplateHead:
return getQuotedEscapedLiteralText("`", node.text, "${");
case SyntaxKind.TemplateMiddle:
return getQuotedEscapedLiteralText("}", node.text, "${");
case SyntaxKind.TemplateTail:
return getQuotedEscapedLiteralText("}", node.text, "`");
case SyntaxKind.NumericLiteral:
return node.text;
}
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
}
function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) {
return leftQuote + escapeNonAsciiCharacters(escapeString(text)) + rightQuote;
}
function emitDownlevelRawTemplateLiteral(node: LiteralExpression) {
// Find original source text, since we need to emit the raw strings of the tagged template.
// The raw strings contain the (escaped) strings of what the user wrote.
@@ -1020,7 +983,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return;
}
const emitOuterParens = isExpression(node.parent)
const emitOuterParens = isPartOfExpression(node.parent)
&& templateNeedsParens(node, <Expression>node.parent);
if (emitOuterParens) {
@@ -1566,7 +1529,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return;
}
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BodyScopedClassBinding) {
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.SelfReferenceInDecoratedClass) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
@@ -1952,7 +1915,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
if (multiLine) {
decreaseIndent();
writeLine();
}
write(")");
@@ -2272,13 +2234,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return forEach(elements, e => e.kind === SyntaxKind.SpreadElementExpression);
}
function skipParentheses(node: Expression): Expression {
function skipParenthesesAndAssertions(node: Expression): Expression {
while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
}
return node;
}
function skipAssertions(node: Expression): Expression {
while (node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
}
return node;
}
function emitCallTarget(node: Expression): Expression {
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword) {
emit(node);
@@ -2296,7 +2265,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
function emitCallWithSpread(node: CallExpression) {
let target: Expression;
const expr = skipParentheses(node.expression);
const expr = skipParenthesesAndAssertions(node.expression);
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
// Target will be emitted as "this" argument
target = emitCallTarget((<PropertyAccessExpression>expr).expression);
@@ -2370,7 +2339,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
superCall = true;
}
else {
superCall = isSuperPropertyOrElementAccess(expression);
superCall = isSuperProperty(expression);
isAsyncMethodWithSuper = superCall && isInAsyncMethodWithSuperInES6(node);
emit(expression);
}
@@ -2610,7 +2579,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
let current = getRootDeclaration(node).parent;
while (current) {
if (current.kind === SyntaxKind.SourceFile) {
return !isExported || ((getCombinedNodeFlags(node) & NodeFlags.Export) !== 0);
return !isExported || ((getCombinedModifierFlags(node) & ModifierFlags.Export) !== 0);
}
else if (isDeclaration(current)) {
return false;
@@ -2728,7 +2697,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
function synthesizedNodeStartsOnNewLine(node: Node) {
return nodeIsSynthesized(node) && (<SynthesizedNode>node).startsOnNewLine;
return nodeIsSynthesized(node) && node.startsOnNewLine;
}
function emitConditionalExpression(node: ConditionalExpression) {
@@ -3345,8 +3314,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
// we can't reuse 'arr' because it might be modified within the body of the loop.
const counter = createTempVariable(TempFlags._i);
const rhsReference = createSynthesizedNode(SyntaxKind.Identifier) as Identifier;
rhsReference.text = node.expression.kind === SyntaxKind.Identifier ?
makeUniqueName((<Identifier>node.expression).text) :
const expressionWithoutAssertions = skipAssertions(node.expression);
rhsReference.text = expressionWithoutAssertions.kind === SyntaxKind.Identifier ?
makeUniqueName((<Identifier>expressionWithoutAssertions).text) :
makeTempVariableName(TempFlags.Auto);
// This is the let keyword for the counter and rhsReference. The let keyword for
@@ -3657,7 +3627,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
function emitModuleMemberName(node: Declaration) {
emitStart(node.name);
if (getCombinedNodeFlags(node) & NodeFlags.Export) {
if (getCombinedModifierFlags(node) & ModifierFlags.Export) {
const container = getContainingModule(node);
if (container) {
write(getGeneratedNameForNode(container));
@@ -3681,7 +3651,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
function emitEs6ExportDefaultCompat(node: Node) {
if (node.parent.kind === SyntaxKind.SourceFile) {
Debug.assert(!!(node.flags & NodeFlags.Default) || node.kind === SyntaxKind.ExportAssignment);
Debug.assert(hasModifier(node, ModifierFlags.Default) || node.kind === SyntaxKind.ExportAssignment);
// only allow export default at a source file level
if (modulekind === ModuleKind.CommonJS || modulekind === ModuleKind.AMD || modulekind === ModuleKind.UMD) {
if (!isEs6Module) {
@@ -3700,7 +3670,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
function emitExportMemberAssignment(node: FunctionLikeDeclaration | ClassDeclaration) {
if (node.flags & NodeFlags.Export) {
if (hasModifier(node, ModifierFlags.Export)) {
writeLine();
emitStart(node);
@@ -3709,7 +3679,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
// emit export default <smth> as
// export("default", <smth>)
write(`${exportFunctionForFile}("`);
if (node.flags & NodeFlags.Default) {
if (hasModifier(node, ModifierFlags.Default)) {
write("default");
}
else {
@@ -3720,7 +3690,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
write(")");
}
else {
if (node.flags & NodeFlags.Default) {
if (hasModifier(node, ModifierFlags.Default)) {
emitEs6ExportDefaultCompat(node);
if (languageVersion === ScriptTarget.ES3) {
write("exports[\"default\"]");
@@ -3851,7 +3821,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
// because actual variable declarations are hoisted
let canDefineTempVariablesInPlace = false;
if (root.kind === SyntaxKind.VariableDeclaration) {
const isExported = getCombinedNodeFlags(root) & NodeFlags.Export;
const isExported = getCombinedModifierFlags(root) & ModifierFlags.Export;
const isSourceLevelForSystemModuleKind = shouldHoistDeclarationInSystemJsModule(root);
canDefineTempVariablesInPlace = !isExported && !isSourceLevelForSystemModuleKind;
}
@@ -4193,7 +4163,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}
function isES6ExportedDeclaration(node: Node) {
return !!(node.flags & NodeFlags.Export) &&
return hasModifier(node, ModifierFlags.Export) &&
modulekind === ModuleKind.ES6 &&
node.parent.kind === SyntaxKind.SourceFile;
}
@@ -4201,7 +4171,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
function emitVariableStatement(node: VariableStatement) {
let startIsEmitted = false;
if (node.flags & NodeFlags.Export) {
if (hasModifier(node, ModifierFlags.Export)) {
if (isES6ExportedDeclaration(node)) {
// Exported ES6 module member
write("export ");
@@ -4230,7 +4200,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
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)) {
if (!hasModifier(node, ModifierFlags.Export)) {
return true;
}
@@ -4361,7 +4331,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
writeLine();
emitStart(restParam);
emitNodeWithCommentsAndWithoutSourcemap(restParam.name);
write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];");
write(`[${tempName} - ${restIndex}] = arguments[${tempName}];`);
emitEnd(restParam);
decreaseIndent();
writeLine();
@@ -4438,7 +4408,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
if (!shouldEmitAsArrowFunction(node)) {
if (isES6ExportedDeclaration(node)) {
write("export ");
if (node.flags & NodeFlags.Default) {
if (hasModifier(node, ModifierFlags.Default)) {
write("default ");
}
}
@@ -4691,7 +4661,7 @@ const _super = (function (geti, seti) {
}
function emitExpressionFunctionBody(node: FunctionLikeDeclaration, body: Expression) {
if (languageVersion < ScriptTarget.ES6 || node.flags & NodeFlags.Async) {
if (languageVersion < ScriptTarget.ES6 || hasModifier(node, ModifierFlags.Async)) {
emitDownLevelExpressionFunctionBody(node, body);
return;
}
@@ -4807,7 +4777,7 @@ const _super = (function (geti, seti) {
function emitParameterPropertyAssignments(node: ConstructorDeclaration) {
forEach(node.parameters, param => {
if (param.flags & NodeFlags.AccessibilityModifier) {
if (hasModifier(param, ModifierFlags.AccessibilityModifier)) {
writeLine();
emitStart(param);
emitStart(param.name);
@@ -4843,7 +4813,7 @@ const _super = (function (geti, seti) {
function getInitializedProperties(node: ClassLikeDeclaration, isStatic: boolean) {
const properties: PropertyDeclaration[] = [];
for (const member of node.members) {
if (member.kind === SyntaxKind.PropertyDeclaration && isStatic === ((member.flags & NodeFlags.Static) !== 0) && (<PropertyDeclaration>member).initializer) {
if (member.kind === SyntaxKind.PropertyDeclaration && isStatic === hasModifier(member, ModifierFlags.Static) && (<PropertyDeclaration>member).initializer) {
properties.push(<PropertyDeclaration>member);
}
}
@@ -4866,7 +4836,7 @@ const _super = (function (geti, seti) {
emit(receiver);
}
else {
if (property.flags & NodeFlags.Static) {
if (hasModifier(property, ModifierFlags.Static)) {
emitDeclarationName(node);
}
else {
@@ -4968,7 +4938,7 @@ const _super = (function (geti, seti) {
writeLine();
emitLeadingComments(member);
emitStart(member);
if (member.flags & NodeFlags.Static) {
if (hasModifier(member, ModifierFlags.Static)) {
write("static ");
}
@@ -5026,7 +4996,7 @@ const _super = (function (geti, seti) {
emitCommentsOnNotEmittedNode(member);
}
// Check if there is any non-static property assignment
if (member.kind === SyntaxKind.PropertyDeclaration && (<PropertyDeclaration>member).initializer && (member.flags & NodeFlags.Static) === 0) {
if (member.kind === SyntaxKind.PropertyDeclaration && (<PropertyDeclaration>member).initializer && !hasModifier(member, ModifierFlags.Static)) {
hasInstancePropertyWithInitializer = true;
}
});
@@ -5233,14 +5203,14 @@ const _super = (function (geti, seti) {
// [Example 4]
//
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.DecoratedClassWithSelfReference) {
decoratedClassAlias = unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default"));
decoratedClassAliases[getNodeId(node)] = decoratedClassAlias;
write(`let ${decoratedClassAlias};`);
writeLine();
}
if (isES6ExportedDeclaration(node) && !(node.flags & NodeFlags.Default)) {
if (isES6ExportedDeclaration(node) && !hasModifier(node, ModifierFlags.Default)) {
write("export ");
}
@@ -5254,7 +5224,7 @@ const _super = (function (geti, seti) {
}
else if (isES6ExportedDeclaration(node)) {
write("export ");
if (node.flags & NodeFlags.Default) {
if (hasModifier(node, ModifierFlags.Default)) {
write("default ");
}
}
@@ -5288,7 +5258,7 @@ const _super = (function (geti, seti) {
// emit name if
// - node has a name
// - this is default export with static initializers
if (node.name || (node.flags & NodeFlags.Default && (staticProperties.length > 0 || modulekind !== ModuleKind.ES6) && !thisNodeIsDecorated)) {
if (node.name || (hasModifier(node, ModifierFlags.Default) && (staticProperties.length > 0 || modulekind !== ModuleKind.ES6) && !thisNodeIsDecorated)) {
write(" ");
emitDeclarationName(node);
}
@@ -5337,7 +5307,7 @@ const _super = (function (geti, seti) {
emitDecoratorsOfClass(node, decoratedClassAlias);
}
if (!(node.flags & NodeFlags.Export)) {
if (!hasModifier(node, ModifierFlags.Export)) {
return;
}
if (modulekind !== ModuleKind.ES6) {
@@ -5346,7 +5316,7 @@ const _super = (function (geti, seti) {
else {
// If this is an exported class, but not on the top level (i.e. on an internal
// module), export it
if (node.flags & NodeFlags.Default) {
if (hasModifier(node, ModifierFlags.Default)) {
// if this is a top level default export of decorated class, write the export after the declaration.
if (thisNodeIsDecorated) {
writeLine();
@@ -5377,6 +5347,18 @@ const _super = (function (geti, seti) {
write(" = ");
}
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
let tempVariable: Identifier;
if (isClassExpressionWithStaticProperties) {
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
write("(");
increaseIndent();
emit(tempVariable);
write(" = ");
}
write("(function (");
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
if (baseTypeNode) {
@@ -5406,9 +5388,6 @@ const _super = (function (geti, seti) {
writeLine();
emitConstructor(node, baseTypeNode);
emitMemberFunctionsForES5AndLower(node);
emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ true));
writeLine();
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
writeLine();
emitToken(SyntaxKind.CloseBraceToken, node.members.end, () => {
write("return ");
@@ -5435,7 +5414,22 @@ const _super = (function (geti, seti) {
write("))");
if (node.kind === SyntaxKind.ClassDeclaration) {
write(";");
emitPropertyDeclarations(node, staticProperties);
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
}
else if (isClassExpressionWithStaticProperties) {
for (const property of staticProperties) {
write(",");
writeLine();
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
}
write(",");
writeLine();
emit(tempVariable);
decreaseIndent();
write(")");
}
emitEnd(node);
if (node.kind === SyntaxKind.ClassDeclaration) {
@@ -5445,14 +5439,14 @@ const _super = (function (geti, seti) {
function emitClassMemberPrefix(node: ClassLikeDeclaration, member: Node) {
emitDeclarationName(node);
if (!(member.flags & NodeFlags.Static)) {
if (!hasModifier(member, ModifierFlags.Static)) {
write(".prototype");
}
}
function emitDecoratorsOfClass(node: ClassLikeDeclaration, decoratedClassAlias: string) {
emitDecoratorsOfMembers(node, /*staticFlag*/ 0);
emitDecoratorsOfMembers(node, NodeFlags.Static);
emitDecoratorsOfMembers(node, ModifierFlags.Static);
emitDecoratorsOfConstructor(node, decoratedClassAlias);
}
@@ -5506,10 +5500,10 @@ const _super = (function (geti, seti) {
writeLine();
}
function emitDecoratorsOfMembers(node: ClassLikeDeclaration, staticFlag: NodeFlags) {
function emitDecoratorsOfMembers(node: ClassLikeDeclaration, staticFlag: ModifierFlags) {
for (const member of node.members) {
// only emit members in the correct group
if ((member.flags & NodeFlags.Static) !== staticFlag) {
if ((getModifierFlags(member) & ModifierFlags.Static) !== staticFlag) {
continue;
}
@@ -5788,7 +5782,7 @@ const _super = (function (geti, seti) {
/** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */
function emitSerializedTypeReferenceNode(node: TypeReferenceNode) {
let location: Node = node.parent;
while (isDeclaration(location) || isTypeNode(location)) {
while (isDeclaration(location) || isPartOfTypeNode(location)) {
location = location.parent;
}
@@ -5970,7 +5964,7 @@ const _super = (function (geti, seti) {
// do not emit var if variable was already hoisted
const isES6ExportedEnum = isES6ExportedDeclaration(node);
if (!(node.flags & NodeFlags.Export) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.EnumDeclaration))) {
if (!hasModifier(node, ModifierFlags.Export) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.EnumDeclaration))) {
emitStart(node);
if (isES6ExportedEnum) {
write("export ");
@@ -5999,7 +5993,7 @@ const _super = (function (geti, seti) {
emitModuleMemberName(node);
write(" = {}));");
emitEnd(node);
if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export && !shouldHoistDeclarationInSystemJsModule(node)) {
if (!isES6ExportedDeclaration(node) && hasModifier(node, ModifierFlags.Export) && !shouldHoistDeclarationInSystemJsModule(node)) {
// do not emit var if variable was already hoisted
writeLine();
emitStart(node);
@@ -6011,7 +6005,7 @@ const _super = (function (geti, seti) {
write(";");
}
if (modulekind !== ModuleKind.ES6 && node.parent === currentSourceFile) {
if (modulekind === ModuleKind.System && (node.flags & NodeFlags.Export)) {
if (modulekind === ModuleKind.System && hasModifier(node, ModifierFlags.Export)) {
// write the call to exporter for enum
writeLine();
write(`${exportFunctionForFile}("`);
@@ -6133,7 +6127,7 @@ const _super = (function (geti, seti) {
}
write(")(");
// write moduleDecl = containingModule.m only if it is not exported es6 module member
if ((node.flags & NodeFlags.Export) && !isES6ExportedDeclaration(node)) {
if (hasModifier(node, ModifierFlags.Export) && !isES6ExportedDeclaration(node)) {
emit(node.name);
write(" = ");
}
@@ -6143,7 +6137,7 @@ const _super = (function (geti, seti) {
write(" = {}));");
emitEnd(node);
if (!isES6ExportedDeclaration(node) && node.name.kind === SyntaxKind.Identifier && node.parent === currentSourceFile) {
if (modulekind === ModuleKind.System && (node.flags & NodeFlags.Export)) {
if (modulekind === ModuleKind.System && hasModifier(node, ModifierFlags.Export)) {
writeLine();
write(`${exportFunctionForFile}("`);
emitDeclarationName(node);
@@ -6255,7 +6249,7 @@ const _super = (function (geti, seti) {
function emitExternalImportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration) {
if (contains(externalImports, node)) {
const isExportedImport = node.kind === SyntaxKind.ImportEqualsDeclaration && (node.flags & NodeFlags.Export) !== 0;
const isExportedImport = node.kind === SyntaxKind.ImportEqualsDeclaration && hasModifier(node, ModifierFlags.Export);
const namespaceDeclaration = getNamespaceDeclarationNode(node);
const varOrConst = (languageVersion <= ScriptTarget.ES5) ? "var " : "const ";
@@ -6345,7 +6339,7 @@ const _super = (function (geti, seti) {
write("export ");
write("var ");
}
else if (!(node.flags & NodeFlags.Export)) {
else if (!hasModifier(node, ModifierFlags.Export)) {
write("var ");
}
}
@@ -6590,7 +6584,8 @@ const _super = (function (geti, seti) {
}
const moduleName = getExternalModuleName(importNode);
if (moduleName.kind === SyntaxKind.StringLiteral) {
return tryRenameExternalModule(<LiteralExpression>moduleName) || getLiteralText(<LiteralExpression>moduleName);
return tryRenameExternalModule(<LiteralExpression>moduleName)
|| getLiteralText(<LiteralExpression>moduleName, currentSourceFile, languageVersion);
}
return undefined;
@@ -6737,7 +6732,7 @@ const _super = (function (geti, seti) {
function writeExportedName(node: Identifier | Declaration): void {
// do not record default exports
// they are local to module and never overwritten (explicitly skipped) by star export
if (node.kind !== SyntaxKind.Identifier && node.flags & NodeFlags.Default) {
if (node.kind !== SyntaxKind.Identifier && hasModifier(node, ModifierFlags.Default)) {
return;
}
@@ -6809,8 +6804,8 @@ const _super = (function (geti, seti) {
emit(local);
}
const flags = getCombinedNodeFlags(local.kind === SyntaxKind.Identifier ? local.parent : local);
if (flags & NodeFlags.Export) {
const flags = getCombinedModifierFlags(local.kind === SyntaxKind.Identifier ? local.parent : local);
if (flags & ModifierFlags.Export) {
if (!exportedDeclarations) {
exportedDeclarations = [];
}
@@ -6825,7 +6820,7 @@ const _super = (function (geti, seti) {
writeLine();
emit(f);
if (f.flags & NodeFlags.Export) {
if (hasModifier(f, ModifierFlags.Export)) {
if (!exportedDeclarations) {
exportedDeclarations = [];
}
@@ -6837,7 +6832,7 @@ const _super = (function (geti, seti) {
return exportedDeclarations;
function visit(node: Node): void {
if (node.flags & NodeFlags.Ambient) {
if (hasModifier(node, ModifierFlags.Ambient)) {
return;
}
@@ -7156,7 +7151,7 @@ const _super = (function (geti, seti) {
}
// text should be quoted string
// for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
// for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
const key = text.substr(1, text.length - 2);
if (hasProperty(groupIndices, key)) {
@@ -7601,7 +7596,7 @@ const _super = (function (geti, seti) {
function emitNodeConsideringCommentsOption(node: Node, emitNodeConsideringSourcemap: (node: Node) => void): void {
if (node) {
if (node.flags & NodeFlags.Ambient) {
if (hasModifier(node, ModifierFlags.Ambient)) {
return emitCommentsOnNotEmittedNode(node);
}
@@ -7973,7 +7968,7 @@ const _super = (function (geti, seti) {
emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
emitComments(currentText, currentLineMap, writer, leadingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitTrailingComments(node: Node) {
@@ -7985,7 +7980,7 @@ const _super = (function (geti, seti) {
const trailingComments = getTrailingCommentsToEmit(node);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
emitComments(currentText, currentLineMap, writer, trailingComments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
}
/**
@@ -8000,8 +7995,8 @@ const _super = (function (geti, seti) {
const trailingComments = getTrailingCommentRanges(currentText, pos);
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
emitComments(currentText, currentLineMap, writer, trailingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitLeadingCommentsOfPositionWorker(pos: number) {
@@ -8022,7 +8017,7 @@ const _super = (function (geti, seti) {
emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
emitComments(currentText, currentLineMap, writer, leadingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
}
function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) {
File diff suppressed because it is too large Load Diff
+104 -114
View File
@@ -1,5 +1,6 @@
/// <reference path="utilities.ts"/>
/// <reference path="scanner.ts"/>
/// <reference path="factory.ts"/>
namespace ts {
/* @internal */ export let parseTime = 0;
@@ -875,7 +876,7 @@ namespace ts {
/** Invokes the provided callback then unconditionally restores the parser to the state it
* was in immediately prior to invoking the callback. The result of invoking the callback
* is returned from this function.
* is returned from this function.
*/
function lookAhead<T>(callback: () => T): T {
return speculationHelper(callback, /*isLookAhead*/ true);
@@ -989,6 +990,16 @@ namespace ts {
return new NodeConstructor(kind, pos, pos);
}
function createNodeArray<T extends Node>(elements?: T[], pos?: number): NodeArray<T> {
const array = <NodeArray<T>>(elements || []);
if (!(pos >= 0)) {
pos = getNodePos();
}
array.pos = pos;
array.end = pos;
return array;
}
function finishNode<T extends Node>(node: T, end?: number): T {
node.end = end === undefined ? scanner.getStartPos() : end;
@@ -1374,8 +1385,7 @@ namespace ts {
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
const saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
const result = <NodeArray<T>>[];
result.pos = getNodePos();
const result = createNodeArray<T>();
while (!isListTerminator(kind)) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
@@ -1722,8 +1732,7 @@ namespace ts {
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimeter?: boolean): NodeArray<T> {
const saveParsingContext = parsingContext;
parsingContext |= 1 << kind;
const result = <NodeArray<T>>[];
result.pos = getNodePos();
const result = createNodeArray<T>();
let commaStart = -1; // Meaning the previous token was not a comma
while (true) {
@@ -1778,12 +1787,8 @@ namespace ts {
return result;
}
function createMissingList<T>(): NodeArray<T> {
const pos = getNodePos();
const result = <NodeArray<T>>[];
result.pos = pos;
result.end = pos;
return result;
function createMissingList<T extends Node>(): NodeArray<T> {
return createNodeArray<T>();
}
function parseBracketedList<T extends Node>(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray<T> {
@@ -1848,8 +1853,7 @@ namespace ts {
template.head = parseTemplateLiteralFragment();
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
const templateSpans = <NodeArray<TemplateSpan>>[];
templateSpans.pos = getNodePos();
const templateSpans = createNodeArray<TemplateSpan>();
do {
templateSpans.push(parseTemplateSpan());
@@ -2002,17 +2006,10 @@ namespace ts {
return token === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token) || token === SyntaxKind.AtToken;
}
function setModifiers(node: Node, modifiers: ModifiersArray) {
if (modifiers) {
node.flags |= modifiers.flags;
node.modifiers = modifiers;
}
}
function parseParameter(): ParameterDeclaration {
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
node.decorators = parseDecorators();
setModifiers(node, parseModifiers());
node.modifiers = parseModifiers();
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
// FormalParameter [Yield,Await]:
@@ -2201,23 +2198,23 @@ namespace ts {
return token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBracketToken;
}
function parseIndexSignatureDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): IndexSignatureDeclaration {
function parseIndexSignatureDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): IndexSignatureDeclaration {
const node = <IndexSignatureDeclaration>createNode(SyntaxKind.IndexSignature, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
node.type = parseTypeAnnotation();
parseTypeMemberSemicolon();
return finishNode(node);
}
function parsePropertyOrMethodSignature(fullStart: number, modifiers: ModifiersArray): PropertySignature | MethodSignature {
function parsePropertyOrMethodSignature(fullStart: number, modifiers: NodeArray<Modifier>): PropertySignature | MethodSignature {
const name = parsePropertyName();
const questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
const method = <MethodSignature>createNode(SyntaxKind.MethodSignature, fullStart);
setModifiers(method, modifiers);
method.modifiers = modifiers;
method.name = name;
method.questionToken = questionToken;
@@ -2229,7 +2226,7 @@ namespace ts {
}
else {
const property = <PropertySignature>createNode(SyntaxKind.PropertySignature, fullStart);
setModifiers(property, modifiers);
property.modifiers = modifiers;
property.name = name;
property.questionToken = questionToken;
property.type = parseTypeAnnotation();
@@ -2425,8 +2422,7 @@ namespace ts {
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
let type = parseConstituentType();
if (token === operator) {
const types = <NodeArray<TypeNode>>[type];
types.pos = type.pos;
const types = createNodeArray<TypeNode>([type], type.pos);
while (parseOptional(operator)) {
types.push(parseConstituentType());
}
@@ -2781,8 +2777,7 @@ namespace ts {
parameter.name = identifier;
finishNode(parameter);
node.parameters = <NodeArray<ParameterDeclaration>>[parameter];
node.parameters.pos = parameter.pos;
node.parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos);
node.parameters.end = parameter.end;
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
@@ -2811,7 +2806,7 @@ namespace ts {
return undefined;
}
const isAsync = !!(arrowFunction.flags & NodeFlags.Async);
const isAsync = !!(getModifierFlags(arrowFunction) & ModifierFlags.Async);
// If we have an arrow, then try to parse the body. Even if not, try to parse if we
// have an opening brace, just in case we're in an error state.
@@ -2956,8 +2951,8 @@ namespace ts {
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction {
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction);
setModifiers(node, parseModifiersForArrowFunction());
const isAsync = !!(node.flags & NodeFlags.Async);
node.modifiers = parseModifiersForArrowFunction();
const isAsync = !!(getModifierFlags(node) & ModifierFlags.Async);
// Arrow functions are never generators.
//
@@ -3557,8 +3552,7 @@ namespace ts {
}
function parseJsxChildren(openingTagName: EntityName): NodeArray<JsxChild> {
const result = <NodeArray<JsxChild>>[];
result.pos = scanner.getStartPos();
const result = createNodeArray<JsxChild>();
const saveParsingContext = parsingContext;
parsingContext |= 1 << ParsingContext.JsxChildren;
@@ -3928,7 +3922,7 @@ namespace ts {
return finishNode(node);
}
function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): AccessorDeclaration {
function tryParseAccessorDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): AccessorDeclaration {
if (parseContextualModifier(SyntaxKind.GetKeyword)) {
return parseAccessorDeclaration(SyntaxKind.GetAccessor, fullStart, decorators, modifiers);
}
@@ -4013,12 +4007,12 @@ namespace ts {
}
const node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression);
setModifiers(node, parseModifiers());
node.modifiers = parseModifiers();
parseExpected(SyntaxKind.FunctionKeyword);
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
const isGenerator = !!node.asteriskToken;
const isAsync = !!(node.flags & NodeFlags.Async);
const isAsync = !!(getModifierFlags(node) & ModifierFlags.Async);
node.name =
isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
isGenerator ? doInYieldContext(parseOptionalIdentifier) :
@@ -4055,6 +4049,10 @@ namespace ts {
function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block {
const node = <Block>createNode(SyntaxKind.Block);
if (parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage) || ignoreMissingOpenBrace) {
if (scanner.hasPrecedingLineBreak()) {
node.multiLine = true;
}
node.statements = parseList(ParsingContext.BlockStatements, parseStatement);
parseExpected(SyntaxKind.CloseBraceToken);
}
@@ -4597,7 +4595,7 @@ namespace ts {
const node = <Statement>createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected);
node.pos = fullStart;
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
return finishNode(node);
}
}
@@ -4732,57 +4730,57 @@ namespace ts {
return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken;
}
function parseVariableStatement(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): VariableStatement {
function parseVariableStatement(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): VariableStatement {
const node = <VariableStatement>createNode(SyntaxKind.VariableStatement, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
parseSemicolon();
return addJSDocComment(finishNode(node));
}
function parseFunctionDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): FunctionDeclaration {
function parseFunctionDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): FunctionDeclaration {
const node = <FunctionDeclaration>createNode(SyntaxKind.FunctionDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.FunctionKeyword);
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
node.name = hasModifier(node, ModifierFlags.Default) ? parseOptionalIdentifier() : parseIdentifier();
const isGenerator = !!node.asteriskToken;
const isAsync = !!(node.flags & NodeFlags.Async);
const isAsync = hasModifier(node, ModifierFlags.Async);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, Diagnostics.or_expected);
return addJSDocComment(finishNode(node));
}
function parseConstructorDeclaration(pos: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ConstructorDeclaration {
function parseConstructorDeclaration(pos: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ConstructorDeclaration {
const node = <ConstructorDeclaration>createNode(SyntaxKind.Constructor, pos);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.ConstructorKeyword);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, Diagnostics.or_expected);
return addJSDocComment(finishNode(node));
}
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
function parseMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, asteriskToken: Node, name: PropertyName, questionToken: Node, diagnosticMessage?: DiagnosticMessage): MethodDeclaration {
const method = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, fullStart);
method.decorators = decorators;
setModifiers(method, modifiers);
method.modifiers = modifiers;
method.asteriskToken = asteriskToken;
method.name = name;
method.questionToken = questionToken;
const isGenerator = !!asteriskToken;
const isAsync = !!(method.flags & NodeFlags.Async);
const isAsync = hasModifier(method, ModifierFlags.Async);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
return addJSDocComment(finishNode(method));
}
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, name: PropertyName, questionToken: Node): ClassElement {
function parsePropertyDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, name: PropertyName, questionToken: Node): ClassElement {
const property = <PropertyDeclaration>createNode(SyntaxKind.PropertyDeclaration, fullStart);
property.decorators = decorators;
setModifiers(property, modifiers);
property.modifiers = modifiers;
property.name = name;
property.questionToken = questionToken;
property.type = parseTypeAnnotation();
@@ -4796,7 +4794,7 @@ namespace ts {
// AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
//
// The checker may still error in the static case to explicitly disallow the yield expression.
property.initializer = modifiers && modifiers.flags & NodeFlags.Static
property.initializer = hasModifier(property, ModifierFlags.Static)
? allowInAnd(parseNonParameterInitializer)
: doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.DisallowInContext, parseNonParameterInitializer);
@@ -4804,7 +4802,7 @@ namespace ts {
return finishNode(property);
}
function parsePropertyOrMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ClassElement {
function parsePropertyOrMethodDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ClassElement {
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
const name = parsePropertyName();
@@ -4823,10 +4821,10 @@ namespace ts {
return parseInitializer(/*inParameter*/ false);
}
function parseAccessorDeclaration(kind: SyntaxKind, fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): AccessorDeclaration {
function parseAccessorDeclaration(kind: SyntaxKind, fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): AccessorDeclaration {
const node = <AccessorDeclaration>createNode(kind, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
node.name = parsePropertyName();
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
@@ -4922,14 +4920,15 @@ namespace ts {
break;
}
if (!decorators) {
decorators = <NodeArray<Decorator>>[];
decorators.pos = decoratorStart;
}
const decorator = <Decorator>createNode(SyntaxKind.Decorator, decoratorStart);
decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
decorators.push(finishNode(decorator));
finishNode(decorator);
if (!decorators) {
decorators = createNodeArray<Decorator>([decorator], decoratorStart);
}
else {
decorators.push(decorator);
}
}
if (decorators) {
decorators.end = getNodeEnd();
@@ -4944,16 +4943,15 @@ namespace ts {
*
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
*/
function parseModifiers(permitInvalidConstAsModifier?: boolean): ModifiersArray {
let flags = 0;
let modifiers: ModifiersArray;
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> {
let modifiers: NodeArray<Modifier>;
while (true) {
const modifierStart = scanner.getStartPos();
const modifierKind = token;
if (token === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) {
// We need to ensure that any subsequent modifiers appear on the same line
// so that when 'const' is a standalone declaration, we don't issue an error.
// so that when 'const' is a standalone declaration, we don't issue an error.
if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
break;
}
@@ -4964,33 +4962,28 @@ namespace ts {
}
}
const modifier = finishNode(createNode(modifierKind, modifierStart));
if (!modifiers) {
modifiers = <ModifiersArray>[];
modifiers.pos = modifierStart;
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
}
else {
modifiers.push(modifier);
}
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
if (modifiers) {
modifiers.flags = flags;
modifiers.end = scanner.getStartPos();
}
return modifiers;
}
function parseModifiersForArrowFunction(): ModifiersArray {
let flags = 0;
let modifiers: ModifiersArray;
function parseModifiersForArrowFunction(): NodeArray<Modifier> {
let modifiers: NodeArray<Modifier>;
if (token === SyntaxKind.AsyncKeyword) {
const modifierStart = scanner.getStartPos();
const modifierKind = token;
nextToken();
modifiers = <ModifiersArray>[];
modifiers.pos = modifierStart;
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
modifiers.flags = flags;
const modifier = finishNode(createNode(modifierKind, modifierStart));
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
modifiers.end = scanner.getStartPos();
}
@@ -5050,14 +5043,14 @@ namespace ts {
SyntaxKind.ClassExpression);
}
function parseClassDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ClassDeclaration {
function parseClassDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ClassDeclaration {
return <ClassDeclaration>parseClassDeclarationOrExpression(fullStart, decorators, modifiers, SyntaxKind.ClassDeclaration);
}
function parseClassDeclarationOrExpression(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, kind: SyntaxKind): ClassLikeDeclaration {
function parseClassDeclarationOrExpression(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, kind: SyntaxKind): ClassLikeDeclaration {
const node = <ClassLikeDeclaration>createNode(kind, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.ClassKeyword);
node.name = parseNameOfClassDeclarationOrExpression();
node.typeParameters = parseTypeParameters();
@@ -5132,10 +5125,10 @@ namespace ts {
return parseList(ParsingContext.ClassMembers, parseClassElement);
}
function parseInterfaceDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): InterfaceDeclaration {
function parseInterfaceDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): InterfaceDeclaration {
const node = <InterfaceDeclaration>createNode(SyntaxKind.InterfaceDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.InterfaceKeyword);
node.name = parseIdentifier();
node.typeParameters = parseTypeParameters();
@@ -5144,10 +5137,10 @@ namespace ts {
return finishNode(node);
}
function parseTypeAliasDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): TypeAliasDeclaration {
function parseTypeAliasDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): TypeAliasDeclaration {
const node = <TypeAliasDeclaration>createNode(SyntaxKind.TypeAliasDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.TypeKeyword);
node.name = parseIdentifier();
node.typeParameters = parseTypeParameters();
@@ -5168,10 +5161,10 @@ namespace ts {
return finishNode(node);
}
function parseEnumDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): EnumDeclaration {
function parseEnumDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): EnumDeclaration {
const node = <EnumDeclaration>createNode(SyntaxKind.EnumDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
parseExpected(SyntaxKind.EnumKeyword);
node.name = parseIdentifier();
if (parseExpected(SyntaxKind.OpenBraceToken)) {
@@ -5196,27 +5189,27 @@ namespace ts {
return finishNode(node);
}
function parseModuleOrNamespaceDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration {
function parseModuleOrNamespaceDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, flags: NodeFlags): ModuleDeclaration {
const node = <ModuleDeclaration>createNode(SyntaxKind.ModuleDeclaration, fullStart);
// If we are parsing a dotted namespace name, we want to
// propagate the 'Namespace' flag across the names if set.
const namespaceFlag = flags & NodeFlags.Namespace;
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
node.flags |= flags;
node.name = parseIdentifier();
node.body = parseOptional(SyntaxKind.DotToken)
? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.Export | namespaceFlag)
? parseModuleOrNamespaceDeclaration(getNodePos(), /*decorators*/ undefined, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag)
: parseModuleBlock();
return finishNode(node);
}
function parseAmbientExternalModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ModuleDeclaration {
function parseAmbientExternalModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ModuleDeclaration {
const node = <ModuleDeclaration>createNode(SyntaxKind.ModuleDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
if (token === SyntaxKind.GlobalKeyword) {
// parse 'global' as name of global scope augmentation
// parse 'global' as name of global scope augmentation
node.name = parseIdentifier();
node.flags |= NodeFlags.GlobalAugmentation;
}
@@ -5227,8 +5220,8 @@ namespace ts {
return finishNode(node);
}
function parseModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ModuleDeclaration {
let flags = modifiers ? modifiers.flags : 0;
function parseModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ModuleDeclaration {
let flags: NodeFlags = 0;
if (token === SyntaxKind.GlobalKeyword) {
// global augmentation
return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
@@ -5258,7 +5251,7 @@ namespace ts {
return nextToken() === SyntaxKind.SlashToken;
}
function parseImportDeclarationOrImportEqualsDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportDeclaration {
function parseImportDeclarationOrImportEqualsDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ImportEqualsDeclaration | ImportDeclaration {
parseExpected(SyntaxKind.ImportKeyword);
const afterImportPos = scanner.getStartPos();
@@ -5271,7 +5264,7 @@ namespace ts {
// import x = M.x;
const importEqualsDeclaration = <ImportEqualsDeclaration>createNode(SyntaxKind.ImportEqualsDeclaration, fullStart);
importEqualsDeclaration.decorators = decorators;
setModifiers(importEqualsDeclaration, modifiers);
importEqualsDeclaration.modifiers = modifiers;
importEqualsDeclaration.name = identifier;
parseExpected(SyntaxKind.EqualsToken);
importEqualsDeclaration.moduleReference = parseModuleReference();
@@ -5283,7 +5276,7 @@ namespace ts {
// Import statement
const importDeclaration = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, fullStart);
importDeclaration.decorators = decorators;
setModifiers(importDeclaration, modifiers);
importDeclaration.modifiers = modifiers;
// ImportDeclaration:
// import ImportClause from ModuleSpecifier ;
@@ -5419,10 +5412,10 @@ namespace ts {
return finishNode(node);
}
function parseExportDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ExportDeclaration {
function parseExportDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ExportDeclaration {
const node = <ExportDeclaration>createNode(SyntaxKind.ExportDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
if (parseOptional(SyntaxKind.AsteriskToken)) {
parseExpected(SyntaxKind.FromKeyword);
node.moduleSpecifier = parseModuleSpecifier();
@@ -5442,10 +5435,10 @@ namespace ts {
return finishNode(node);
}
function parseExportAssignment(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ExportAssignment {
function parseExportAssignment(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>): ExportAssignment {
const node = <ExportAssignment>createNode(SyntaxKind.ExportAssignment, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.modifiers = modifiers;
if (parseOptional(SyntaxKind.EqualsToken)) {
node.isExportEquals = true;
}
@@ -5524,7 +5517,7 @@ namespace ts {
function setExternalModuleIndicator(sourceFile: SourceFile) {
sourceFile.externalModuleIndicator = forEach(sourceFile.statements, node =>
node.flags & NodeFlags.Export
hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
@@ -5848,10 +5841,8 @@ namespace ts {
function parseJSDocTypeList(firstType: JSDocType) {
Debug.assert(!!firstType);
const types = <NodeArray<JSDocType>>[];
types.pos = firstType.pos;
const types = createNodeArray([firstType], firstType.pos);
types.push(firstType);
while (parseOptional(SyntaxKind.BarToken)) {
types.push(parseJSDocType());
}
@@ -6059,11 +6050,11 @@ namespace ts {
function addTag(tag: JSDocTag): void {
if (tag) {
if (!tags) {
tags = <NodeArray<JSDocTag>>[];
tags.pos = tag.pos;
tags = createNodeArray([tag], tag.pos);
}
else {
tags.push(tag);
}
tags.push(tag);
tags.end = tag.end;
}
}
@@ -6156,8 +6147,7 @@ namespace ts {
}
// Type parameter list looks like '@template T,U,V'
const typeParameters = <NodeArray<TypeParameterDeclaration>>[];
typeParameters.pos = scanner.getStartPos();
const typeParameters = createNodeArray<TypeParameterDeclaration>();
while (true) {
const name = parseJSDocIdentifier();
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -1,6 +1,7 @@
/// <reference path="sys.ts" />
/// <reference path="emitter.ts" />
/// <reference path="core.ts" />
/// <reference path="printer.ts" />
namespace ts {
/* @internal */ export let programTime = 0;
@@ -968,7 +969,8 @@ namespace ts {
const start = new Date().getTime();
const emitResult = emitFiles(
const fileEmitter = options.experimentalTransforms ? printFiles : emitFiles;
const emitResult = fileEmitter(
emitResolver,
getEmitHost(writeFileCallback),
sourceFile);
@@ -1194,7 +1196,7 @@ namespace ts {
return false;
}
function checkModifiers(modifiers: ModifiersArray): boolean {
function checkModifiers(modifiers: NodeArray<Modifier>): boolean {
if (modifiers) {
for (const modifier of modifiers) {
switch (modifier.kind) {
@@ -1309,7 +1311,7 @@ namespace ts {
}
break;
case SyntaxKind.ModuleDeclaration:
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || isDeclarationFile(file))) {
const moduleName = <LiteralExpression>(<ModuleDeclaration>node).name;
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
// This will happen in two cases:
@@ -1719,7 +1721,7 @@ namespace ts {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
}
if (options.reactNamespace && !isIdentifier(options.reactNamespace, languageVersion)) {
if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace));
}
+3 -4
View File
@@ -433,9 +433,7 @@ namespace ts {
/* @internal */
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
// Using ! with a greater than test is a fast way of testing the following conditions:
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
if (!(pos >= 0)) {
if (positionIsSynthesized(pos)) {
return pos;
}
@@ -642,6 +640,7 @@ namespace ts {
pos++;
}
}
if (collecting) {
if (!result) {
result = [];
@@ -696,7 +695,7 @@ namespace ts {
}
/* @internal */
export function isIdentifier(name: string, languageVersion: ScriptTarget): boolean {
export function isIdentifierText(name: string, languageVersion: ScriptTarget): boolean {
if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
return false;
}
+44 -4
View File
@@ -7,12 +7,15 @@ namespace ts {
setSourceFile(sourceFile: SourceFile): void;
emitPos(pos: number): void;
emitStart(range: TextRange): void;
emitEnd(range: TextRange, stopOverridingSpan?: boolean): void;
changeEmitSourcePos(): void;
emitEnd(range: TextRange): void;
/*@deprecated*/ emitEnd(range: TextRange, stopOverridingSpan: boolean): void;
/*@deprecated*/ changeEmitSourcePos(): void;
getText(): string;
getSourceMappingURL(): string;
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
reset(): void;
enable(): void;
disable(): void;
}
let nullSourceMapWriter: SourceMapWriter;
@@ -38,6 +41,8 @@ namespace ts {
getSourceMappingURL(): string { return undefined; },
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void { },
reset(): void { },
enable(): void { },
disable(): void { }
};
}
@@ -62,6 +67,13 @@ namespace ts {
// Source map data
let sourceMapData: SourceMapData;
// This keeps track of the number of times `disable` has been called without a
// corresponding call to `enable`. As long as this value is non-zero, mappings will not
// be recorded.
// This is primarily used to provide a better experience when debugging binding
// patterns and destructuring assignments for simple expressions.
let disableDepth: number;
return {
getSourceMapData: () => sourceMapData,
setSourceFile,
@@ -73,6 +85,8 @@ namespace ts {
getSourceMappingURL,
initialize,
reset,
enable,
disable,
};
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
@@ -81,6 +95,7 @@ namespace ts {
}
currentSourceFile = undefined;
disableDepth = 0;
// Current source map file and its index in the sources list
sourceMapSourceIndex = -1;
@@ -147,6 +162,23 @@ namespace ts {
lastEncodedSourceMapSpan = undefined;
lastEncodedNameIndex = undefined;
sourceMapData = undefined;
disableDepth = 0;
}
/**
* Re-enables the recording of mappings.
*/
function enable() {
if (disableDepth > 0) {
disableDepth--;
}
}
/**
* Disables the recording of mappings.
*/
function disable() {
disableDepth++;
}
function updateLastEncodedAndRecordedSpans() {
@@ -168,7 +200,7 @@ namespace ts {
sourceMapData.sourceMapDecodedMappings[sourceMapData.sourceMapDecodedMappings.length - 1] :
defaultLastEncodedSourceMapSpan;
// TODO: Update lastEncodedNameIndex
// TODO: Update lastEncodedNameIndex
// Since we dont support this any more, lets not worry about it right now.
// When we start supporting nameIndex, we will get back to this
@@ -236,7 +268,7 @@ namespace ts {
}
function emitPos(pos: number) {
if (pos === -1) {
if (positionIsSynthesized(pos) || disableDepth > 0) {
return;
}
@@ -288,9 +320,17 @@ namespace ts {
function emitStart(range: TextRange) {
emitPos(getStartPos(range));
if (range.disableSourceMap) {
disable();
}
}
function emitEnd(range: TextRange, stopOverridingEnd?: boolean) {
if (range.disableSourceMap) {
enable();
}
emitPos(range.end);
stopOverridingSpan = stopOverridingEnd;
}
+11
View File
@@ -8,6 +8,7 @@ namespace ts {
args: string[];
newLine: string;
useCaseSensitiveFileNames: boolean;
/*@internal*/ developmentMode?: boolean;
write(s: string): void;
readFile(path: string, encoding?: string): string;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
@@ -22,6 +23,7 @@ namespace ts {
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
getMemoryUsage?(): number;
exit(exitCode?: number): void;
/*@internal*/ tryEnableSourceMapsForHost?(): void;
}
interface WatchedFile {
@@ -494,6 +496,7 @@ namespace ts {
args: process.argv.slice(2),
newLine: _os.EOL,
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
developmentMode: /^development$/i.test(String(process.env.NODE_ENV)),
write(s: string): void {
process.stdout.write(s);
},
@@ -564,6 +567,14 @@ namespace ts {
},
exit(exitCode?: number): void {
process.exit(exitCode);
},
tryEnableSourceMapsForHost() {
try {
require("source-map-support").install();
}
catch (e) {
// Could not enable source maps.
}
}
};
}
+291
View File
@@ -0,0 +1,291 @@
/// <reference path="visitor.ts" />
/// <reference path="transformers/ts.ts" />
/// <reference path="transformers/jsx.ts" />
/// <reference path="transformers/es7.ts" />
/// <reference path="transformers/es6.ts" />
/// <reference path="transformers/module/module.ts" />
/// <reference path="transformers/module/system.ts" />
/// <reference path="transformers/module/es6.ts" />
/* @internal */
namespace ts {
const moduleTransformerMap: Map<Transformer> = {
[ModuleKind.ES6]: transformES6Module,
[ModuleKind.System]: transformSystemModule,
[ModuleKind.AMD]: transformModule,
[ModuleKind.CommonJS]: transformModule,
[ModuleKind.UMD]: transformModule,
[ModuleKind.None]: transformModule,
};
const enum SyntaxKindFeatureFlags {
ExpressionSubstitution = 1 << 0,
EmitNotifications = 1 << 1,
}
export function getTransformers(compilerOptions: CompilerOptions) {
const jsx = compilerOptions.jsx;
const languageVersion = getEmitScriptTarget(compilerOptions);
const moduleKind = getEmitModuleKind(compilerOptions);
const transformers: Transformer[] = [];
transformers.push(transformTypeScript);
transformers.push(moduleTransformerMap[moduleKind]);
if (jsx === JsxEmit.React) {
transformers.push(transformJsx);
}
transformers.push(transformES7);
if (languageVersion < ScriptTarget.ES6) {
transformers.push(transformES6);
}
return transformers;
}
/**
* Transforms an array of SourceFiles by passing them through each transformer.
*
* @param resolver The emit resolver provided by the checker.
* @param host The emit host.
* @param sourceFiles An array of source files
* @param transforms An array of Transformers.
*/
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
const nodeEmitFlags: NodeEmitFlags[] = [];
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
let lexicalEnvironmentStackOffset = 0;
let hoistedVariableDeclarations: VariableDeclaration[];
let hoistedFunctionDeclarations: FunctionDeclaration[];
let currentSourceFile: SourceFile;
// The transformation context is provided to each transformer as part of transformer
// initialization.
const context: TransformationContext = {
getCompilerOptions: () => host.getCompilerOptions(),
getEmitResolver: () => resolver,
getNodeEmitFlags,
setNodeEmitFlags,
hoistVariableDeclaration,
hoistFunctionDeclaration,
startLexicalEnvironment,
endLexicalEnvironment,
identifierSubstitution: node => node,
expressionSubstitution: node => node,
enableExpressionSubstitution,
isExpressionSubstitutionEnabled,
onEmitNode: (node, emit) => emit(node),
enableEmitNotification,
isEmitNotificationEnabled,
};
// Chain together and initialize each transformer.
const transformation = chain(...transformers)(context);
// Transform each source file.
return map(sourceFiles, transformSourceFile);
/**
* Transforms a source file.
*
* @param sourceFile The source file to transform.
*/
function transformSourceFile(sourceFile: SourceFile) {
if (isDeclarationFile(sourceFile)) {
return sourceFile;
}
currentSourceFile = sourceFile;
return transformation(sourceFile);
}
function enableExpressionSubstitution(kind: SyntaxKind) {
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.ExpressionSubstitution;
}
function isExpressionSubstitutionEnabled(node: Node) {
return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.ExpressionSubstitution) !== 0;
}
function enableEmitNotification(kind: SyntaxKind) {
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.EmitNotifications;
}
function isEmitNotificationEnabled(node: Node) {
return (enabledSyntaxKindFeatures[node.kind] & SyntaxKindFeatureFlags.EmitNotifications) !== 0
|| (getNodeEmitFlags(node) & NodeEmitFlags.AdviseOnEmitNode) !== 0;
}
/**
* Gets flags that control emit behavior of a node.
*/
function getNodeEmitFlags(node: Node) {
while (node) {
const nodeId = getNodeId(node);
if (nodeEmitFlags[nodeId] !== undefined) {
return nodeEmitFlags[nodeId];
}
node = node.original;
}
return undefined;
}
/**
* Sets flags that control emit behavior of a node.
*/
function setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags) {
nodeEmitFlags[getNodeId(node)] = flags;
return node;
}
/**
* Records a hoisted variable declaration for the provided name within a lexical environment.
*/
function hoistVariableDeclaration(name: Identifier): void {
const decl = createVariableDeclaration(name);
if (!hoistedVariableDeclarations) {
hoistedVariableDeclarations = [decl];
}
else {
hoistedVariableDeclarations.push(decl);
}
}
/**
* Records a hoisted function declaration within a lexical environment.
*/
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
if (!hoistedFunctionDeclarations) {
hoistedFunctionDeclarations = [func];
}
else {
hoistedFunctionDeclarations.push(func);
}
}
/**
* Starts a new lexical environment. Any existing hoisted variable or function declarations
* are pushed onto a stack, and the related storage variables are reset.
*/
function startLexicalEnvironment(): void {
// Save the current lexical environment. Rather than resizing the array we adjust the
// stack size variable. This allows us to reuse existing array slots we've
// already allocated between transformations to avoid allocation and GC overhead during
// transformation.
lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = hoistedVariableDeclarations;
lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = hoistedFunctionDeclarations;
lexicalEnvironmentStackOffset++;
hoistedVariableDeclarations = undefined;
hoistedFunctionDeclarations = undefined;
}
/**
* Ends a lexical environment. The previous set of hoisted declarations are restored and
* any hoisted declarations added in this environment are returned.
*/
function endLexicalEnvironment(): Statement[] {
let statements: Statement[];
if (hoistedVariableDeclarations || hoistedFunctionDeclarations) {
if (hoistedFunctionDeclarations) {
statements = [...hoistedFunctionDeclarations];
}
if (hoistedVariableDeclarations) {
const statement = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(hoistedVariableDeclarations)
);
if (!statements) {
statements = [statement];
}
else {
statements.push(statement);
}
}
}
// Restore the previous lexical environment.
lexicalEnvironmentStackOffset--;
hoistedVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
hoistedFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
return statements;
}
}
/**
* High-order function, creates a function that executes a function composition.
* For example, `chain(a, b)` is the equivalent of `x => ((a', b') => y => b'(a'(y)))(a(x), b(x))`
*
* @param args The functions to chain.
*/
function chain<T, U>(...args: ((t: T) => (u: U) => U)[]): (t: T) => (u: U) => U;
function chain<T, U>(a: (t: T) => (u: U) => U, b: (t: T) => (u: U) => U, c: (t: T) => (u: U) => U, d: (t: T) => (u: U) => U, e: (t: T) => (u: U) => U): (t: T) => (u: U) => U {
if (e) {
const args = arrayOf<(t: T) => (u: U) => U>(arguments);
return t => compose(...map(args, f => f(t)));
}
else if (d) {
return t => compose(a(t), b(t), c(t), d(t));
}
else if (c) {
return t => compose(a(t), b(t), c(t));
}
else if (b) {
return t => compose(a(t), b(t));
}
else if (a) {
return t => compose(a(t));
}
else {
return t => u => u;
}
}
/**
* High-order function, composes functions. Note that functions are composed inside-out;
* for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
*
* @param args The functions to compose.
*/
function compose<T>(...args: ((t: T) => T)[]): (t: T) => T;
function compose<T>(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t: T) => T, e: (t: T) => T): (t: T) => T {
if (e) {
const args = arrayOf(arguments);
return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t);
}
else if (d) {
return t => d(c(b(a(t))));
}
else if (c) {
return t => c(b(a(t)));
}
else if (b) {
return t => b(a(t));
}
else if (a) {
return t => a(t);
}
else {
return t => t;
}
}
/**
* Makes an array from an ArrayLike.
*/
function arrayOf<T>(arrayLike: ArrayLike<T>) {
const length = arrayLike.length;
const array: T[] = new Array<T>(length);
for (let i = 0; i < length; i++) {
array[i] = arrayLike[i];
}
return array;
}
}
+397
View File
@@ -0,0 +1,397 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
/**
* Flattens a destructuring assignment expression.
*
* @param root The destructuring assignment expression.
* @param needsValue Indicates whether the value from the right-hand-side of the
* destructuring assignment is needed as part of a larger expression.
* @param recordTempVariable A callback used to record new temporary variables.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenDestructuringAssignment(
node: BinaryExpression,
needsValue: boolean,
recordTempVariable: (node: Identifier) => void,
visitor?: (node: Node) => VisitResult<Node>) {
if (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
return node.right;
}
let location: TextRange = node;
let value = node.right;
const expressions: Expression[] = [];
if (needsValue) {
// If the right-hand value of the destructuring assignment needs to be preserved (as
// is the case when the destructuring assignmen) is part of a larger expression),
// then we need to cache the right-hand value.
//
// The source map location for the assignment should point to the entire binary
// expression.
value = ensureIdentifier(node.right, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
}
else if (nodeIsSynthesized(node)) {
// Generally, the source map location for a destructuring assignment is the root
// expression.
//
// However, if the root expression is synthesized (as in the case
// of the initializer when transforming a ForOfStatement), then the source map
// location should point to the right-hand value of the expression.
location = node.right;
}
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
if (needsValue) {
expressions.push(value);
}
const expression = inlineExpressions(expressions);
aggregateTransformFlags(expression);
return expression;
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
const expression = createAssignment(name, value, location);
if (isSimpleExpression(value)) {
expression.disableSourceMap = true;
}
aggregateTransformFlags(expression);
expressions.push(expression);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable();
recordTempVariable(name);
emitAssignment(name, value, location);
return name;
}
}
/**
* Flattens binding patterns in a parameter declaration.
*
* @param node The ParameterDeclaration to flatten.
* @param value The rhs value for the binding pattern.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenParameterDestructuring(node: ParameterDeclaration, value: Expression, visitor?: (node: Node) => VisitResult<Node>) {
const declarations: VariableDeclaration[] = [];
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
const declaration = createVariableDeclaration(name, value, location);
if (isSimpleExpression(value)) {
declaration.disableSourceMap = true;
}
aggregateTransformFlags(declaration);
declarations.push(declaration);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable();
emitAssignment(name, value, location);
return name;
}
}
/**
* Flattens binding patterns in a variable declaration.
*
* @param node The VariableDeclaration to flatten.
* @param value An optional rhs value for the binding pattern.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenVariableDestructuring(node: VariableDeclaration, value?: Expression, visitor?: (node: Node) => VisitResult<Node>) {
const declarations: VariableDeclaration[] = [];
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
const declaration = createVariableDeclaration(name, value, location);
if (declarations.length === 0) {
declaration.pos = -1;
}
if (isSimpleExpression(value)) {
declaration.disableSourceMap = true;
}
declaration.original = original;
declarations.push(declaration);
aggregateTransformFlags(declaration);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable();
emitAssignment(name, value, location, /*original*/ undefined);
return name;
}
}
/**
* Flattens binding patterns in a variable declaration and transforms them into an expression.
*
* @param node The VariableDeclaration to flatten.
* @param recordTempVariable A callback used to record new temporary variables.
* @param nameSubstitution An optional callback used to substitute binding names.
* @param visitor An optional visitor to use to visit expressions.
*/
export function flattenVariableDestructuringToExpression(
node: VariableDeclaration,
recordTempVariable: (name: Identifier) => void,
nameSubstitution?: (name: Identifier) => Expression,
visitor?: (node: Node) => VisitResult<Node>) {
const pendingAssignments: Expression[] = [];
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment);
const expression = inlineExpressions(pendingAssignments);
aggregateTransformFlags(expression);
return expression;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
const left = nameSubstitution && nameSubstitution(name) || name;
emitPendingAssignment(left, value, location, original);
}
function emitTempVariableAssignment(value: Expression, location: TextRange) {
const name = createTempVariable();
recordTempVariable(name);
emitPendingAssignment(name, value, location, /*original*/ undefined);
return name;
}
function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) {
const expression = createAssignment(name, value, location);
if (isSimpleExpression(value)) {
expression.disableSourceMap = true;
}
expression.original = original;
pendingAssignments.push(expression);
return expression;
}
}
function flattenDestructuring(
root: BindingElement | BinaryExpression,
value: Expression,
location: TextRange,
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
emitTempVariableAssignment: (value: Expression, location: TextRange) => Identifier,
visitor?: (node: Node) => VisitResult<Node>) {
if (value && visitor) {
value = visitNode(value, visitor, isExpression);
}
if (isBinaryExpression(root)) {
emitDestructuringAssignment(root.left, value, location);
}
else {
emitBindingElement(root, value);
}
function emitDestructuringAssignment(bindingTarget: Expression | ShorthandPropertyAssignment, value: Expression, location: TextRange) {
// When emitting target = value use source map node to highlight, including any temporary assignments needed for this
let target: Expression;
if (isShorthandPropertyAssignment(bindingTarget)) {
const initializer = visitor
? visitNode(bindingTarget.objectAssignmentInitializer, visitor, isExpression)
: bindingTarget.objectAssignmentInitializer;
if (initializer) {
value = createDefaultValueCheck(value, initializer, location);
}
target = bindingTarget.name;
}
else if (isBinaryExpression(bindingTarget) && bindingTarget.operatorToken.kind === SyntaxKind.EqualsToken) {
const initializer = visitor
? visitNode(bindingTarget.right, visitor, isExpression)
: bindingTarget.right;
value = createDefaultValueCheck(value, initializer, location);
target = bindingTarget.left;
}
else {
target = bindingTarget;
}
if (target.kind === SyntaxKind.ObjectLiteralExpression) {
emitObjectLiteralAssignment(<ObjectLiteralExpression>target, value, location);
}
else if (target.kind === SyntaxKind.ArrayLiteralExpression) {
emitArrayLiteralAssignment(<ArrayLiteralExpression>target, value, location);
}
else {
const name = getRelocatedClone(<Identifier>target, /*location*/ target);
emitAssignment(name, value, location, /*original*/ undefined);
}
}
function emitObjectLiteralAssignment(target: ObjectLiteralExpression, value: Expression, location: TextRange) {
const properties = target.properties;
if (properties.length !== 1) {
// For anything but a single element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once.
// When doing so we want to hightlight the passed in source map node since thats the one needing this temp assignment
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
}
for (const p of properties) {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
const propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
const target = p.kind === SyntaxKind.ShorthandPropertyAssignment ? <ShorthandPropertyAssignment>p : (<PropertyAssignment>p).initializer || propName;
// Assignment for target = value.propName should highligh whole property, hence use p as source map node
emitDestructuringAssignment(target, createDestructuringPropertyAccess(value, propName), p);
}
}
}
function emitArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, location: TextRange) {
const elements = target.elements;
const numElements = elements.length;
if (numElements !== 1) {
// For anything but a single element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once.
// When doing so we want to hightlight the passed in source map node since thats the one needing this temp assignment
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
}
for (let i = 0; i < numElements; i++) {
const e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
// Assignment for target = value.propName should highligh whole property, hence use e as source map node
if (e.kind !== SyntaxKind.SpreadElementExpression) {
emitDestructuringAssignment(e, createElementAccess(value, createLiteral(i)), e);
}
else if (i === numElements - 1) {
emitDestructuringAssignment((<SpreadElementExpression>e).expression, createArraySlice(value, i), e);
}
}
}
}
function emitBindingElement(target: BindingElement, value: Expression) {
// Any temporary assignments needed to emit target = value should point to target
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
if (initializer) {
// Combine value and initializer
value = value ? createDefaultValueCheck(value, initializer, target) : initializer;
}
else if (!value) {
// Use 'void 0' in absence of value and initializer
value = createVoidZero();
}
const name = target.name;
if (isBindingPattern(name)) {
const elements = name.elements;
const numElements = elements.length;
if (numElements !== 1) {
// For anything other than a single-element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once. Additionally, if we have zero elements
// we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
// so in that case, we'll intentionally create that temporary.
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ numElements !== 0, target, emitTempVariableAssignment);
}
for (let i = 0; i < numElements; i++) {
const element = elements[i];
if (name.kind === SyntaxKind.ObjectBindingPattern) {
// Rewrite element to a declaration with an initializer that fetches property
const propName = element.propertyName || <Identifier>element.name;
emitBindingElement(element, createDestructuringPropertyAccess(value, propName));
}
else if (element.kind !== SyntaxKind.OmittedExpression) {
if (!element.dotDotDotToken) {
// Rewrite element to a declaration that accesses array element at index i
emitBindingElement(element, createElementAccess(value, i));
}
else if (i === numElements - 1) {
emitBindingElement(element, createArraySlice(value, i));
}
}
}
}
else {
const clonedName = getSynthesizedClone(name);
emitAssignment(clonedName, value, target, target);
}
}
function createDefaultValueCheck(value: Expression, defaultValue: Expression, location: TextRange): Expression {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
return createConditional(
createStrictEquality(value, createVoidZero()),
defaultValue,
value
);
}
/**
* Creates either a PropertyAccessExpression or an ElementAccessExpression for the
* right-hand side of a transformed destructuring assignment.
*
* @param expression The right-hand expression that is the source of the property.
* @param propertyName The destructuring property name.
*/
function createDestructuringPropertyAccess(expression: Expression, propertyName: PropertyName): LeftHandSideExpression {
if (isComputedPropertyName(propertyName)) {
return createElementAccess(
expression,
ensureIdentifier(propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName, emitTempVariableAssignment)
);
}
else if (isIdentifier(propertyName)) {
return createPropertyAccess(
expression,
propertyName.text
);
}
else {
// We create a synthetic copy of the identifier in order to avoid the rewriting that might
// otherwise occur when the identifier is emitted.
return createElementAccess(
expression,
getSynthesizedClone(propertyName)
);
}
}
}
/**
* Ensures that there exists a declared identifier whose value holds the given expression.
* This function is useful to ensure that the expression's value can be read from in subsequent expressions.
* Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
*
* @param value the expression whose value needs to be bound.
* @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
* false if it is necessary to always emit an identifier.
* @param location The location to use for source maps and comments.
* @param emitTempVariableAssignment A callback used to emit a temporary variable.
*/
function ensureIdentifier(
value: Expression,
reuseIdentifierExpressions: boolean,
location: TextRange,
emitTempVariableAssignment: (value: Expression, location: TextRange) => Identifier) {
if (isIdentifier(value) && reuseIdentifierExpressions) {
return value;
}
else {
return emitTempVariableAssignment(value, location);
}
}
}
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
export function transformES7(context: TransformationContext) {
const { hoistVariableDeclaration } = context;
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
return visitEachChild(node, visitor, context);
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.ES7) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsES7) {
return visitEachChild(node, visitor, context);
}
else {
return node;
}
}
function visitorWorker(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.BinaryExpression:
return visitBinaryExpression(<BinaryExpression>node);
default:
Debug.failBadSyntaxKind(node);
return visitEachChild(node, visitor, context);
}
}
function visitBinaryExpression(node: BinaryExpression): Expression {
// We are here because ES7 adds support for the exponentiation operator.
const left = visitNode(node.left, visitor, isExpression);
const right = visitNode(node.right, visitor, isExpression);
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
let target: Expression;
let value: Expression;
if (isElementAccessExpression(left)) {
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
const expressionTemp = createTempVariable();
hoistVariableDeclaration(expressionTemp);
const argumentExpressionTemp = createTempVariable();
hoistVariableDeclaration(argumentExpressionTemp);
target = createElementAccess(
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
/*location*/ left
);
value = createElementAccess(
expressionTemp,
argumentExpressionTemp,
/*location*/ left
);
}
else if (isPropertyAccessExpression(left)) {
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
const expressionTemp = createTempVariable();
hoistVariableDeclaration(expressionTemp);
target = createPropertyAccess(
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
left.name,
/*location*/ left
);
value = createPropertyAccess(
expressionTemp,
left.name,
/*location*/ left
);
}
else {
// Transforms `a **= b` into `a = Math.pow(a, b)`
target = left;
value = left;
}
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
}
else if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskToken) {
// Transforms `a ** b` into `Math.pow(a, b)`
return createMathPow(left, right, /*location*/ node);
}
else {
Debug.failBadSyntaxKind(node);
return visitEachChild(node, visitor, context);
}
}
}
}
+490
View File
@@ -0,0 +1,490 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
const entities: Map<number> = createEntitiesMap();
export function transformJsx(context: TransformationContext) {
const compilerOptions = context.getCompilerOptions();
return transformSourceFile;
/**
* Transform JSX-specific syntax in a SourceFile.
*
* @param node A SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
return visitEachChild(node, visitor, context);
}
function visitor(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.Jsx) {
return visitorWorker(node);
}
else if (node.transformFlags & TransformFlags.ContainsJsx) {
return visitEachChild(node, visitor, context);
}
else {
return node;
}
}
function visitorWorker(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.JsxElement:
return visitJsxElement(<JsxElement>node);
case SyntaxKind.JsxSelfClosingElement:
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
default:
Debug.failBadSyntaxKind(node);
return undefined;
}
}
function transformJsxChildToExpression(node: JsxChild): Expression {
switch (node.kind) {
case SyntaxKind.JsxText:
return visitJsxText(<JsxText>node);
case SyntaxKind.JsxExpression:
return visitJsxExpression(<JsxExpression>node);
case SyntaxKind.JsxElement:
return visitJsxElement(<JsxElement>node);
case SyntaxKind.JsxSelfClosingElement:
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
default:
Debug.failBadSyntaxKind(node);
return undefined;
}
}
function visitJsxElement(node: JsxElement) {
return visitJsxOpeningLikeElement(node.openingElement, node.children);
}
function visitJsxSelfClosingElement(node: JsxSelfClosingElement) {
return visitJsxOpeningLikeElement(node, /*children*/ undefined);
}
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[]) {
const tagName = getTagName(node);
let objectProperties: Expression;
const attrs = node.attributes;
if (attrs.length === 0) {
// When there are no attributes, React wants "null"
objectProperties = createNull();
}
else {
// Map spans of JsxAttribute nodes into object literals and spans
// of JsxSpreadAttribute nodes into expressions.
const segments = flatten(
spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread
? map(attrs, transformJsxSpreadAttributeToExpression)
: createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement))
)
);
if (isJsxSpreadAttribute(attrs[0])) {
// We must always emit at least one object literal before a spread
// argument.
segments.unshift(createObjectLiteral());
}
// Either emit one big object literal (no spread attribs), or
// a call to React.__spread
objectProperties = singleOrUndefined(segments)
|| createJsxSpread(compilerOptions.reactNamespace, segments);
}
return createJsxCreateElement(
compilerOptions.reactNamespace,
tagName,
objectProperties,
filter(map(children, transformJsxChildToExpression), isDefined)
);
}
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
return visitNode(node.expression, visitor, isExpression);
}
function transformJsxAttributeToObjectLiteralElement(node: JsxAttribute) {
const name = getAttributeName(node);
const expression = node.initializer
? visitNode(node.initializer, visitor, isExpression)
: createLiteral(true);
return createPropertyAssignment(name, expression);
}
function visitJsxText(node: JsxText) {
const text = getTextOfNode(node, /*includeTrivia*/ true);
let parts: Expression[];
let firstNonWhitespace = 0;
let lastNonWhitespace = -1;
// JSX trims whitespace at the end and beginning of lines, except that the
// start/end of a tag is considered a start/end of a line only if that line is
// on the same line as the closing tag. See examples in
// tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
for (let i = 0; i < text.length; i++) {
const c = text.charCodeAt(i);
if (isLineBreak(c)) {
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
const part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
if (!parts) {
parts = [];
}
// We do not escape the string here as that is handled by the printer
// when it emits the literal. We do, however, need to decode JSX entities.
parts.push(createLiteral(decodeEntities(part)));
}
firstNonWhitespace = -1;
}
else if (!isWhiteSpace(c)) {
lastNonWhitespace = i;
if (firstNonWhitespace === -1) {
firstNonWhitespace = i;
}
}
}
if (firstNonWhitespace !== -1) {
const part = text.substr(firstNonWhitespace);
if (!parts) {
parts = [];
}
// We do not escape the string here as that is handled by the printer
// when it emits the literal. We do, however, need to decode JSX entities.
parts.push(createLiteral(decodeEntities(part)));
}
if (parts) {
return reduceLeft(parts, aggregateJsxTextParts);
}
return undefined;
}
/**
* Aggregates two expressions by interpolating them with a whitespace literal.
*/
function aggregateJsxTextParts(left: Expression, right: Expression) {
return createAdd(createAdd(left, createLiteral(" ")), right);
}
/**
* Decodes JSX entities.
*/
function decodeEntities(text: string) {
return text.replace(/&(\w+);/g, function(s: any, m: string) {
if (entities[m] !== undefined) {
return String.fromCharCode(entities[m]);
}
else {
return s;
}
});
}
function getTagName(node: JsxElement | JsxOpeningLikeElement): Expression {
if (node.kind === SyntaxKind.JsxElement) {
return getTagName((<JsxElement>node).openingElement);
}
else {
const name = (<JsxOpeningLikeElement>node).tagName;
if (isIdentifier(name) && isIntrinsicJsxName(name.text)) {
return createLiteral(name.text);
}
else {
return createExpressionFromEntityName(name);
}
}
}
/**
* Emit an attribute name, which is quoted if it needs to be quoted. Because
* these emit into an object literal property name, we don't need to be worried
* about keywords, just non-identifier characters
*/
function getAttributeName(node: JsxAttribute): StringLiteral | Identifier {
const name = node.name;
if (/^[A-Za-z_]\w*$/.test(name.text)) {
return createLiteral(name.text);
}
else {
return name;
}
}
function visitJsxExpression(node: JsxExpression) {
return visitNode(node.expression, visitor, isExpression);
}
}
function createEntitiesMap(): Map<number> {
return {
"quot": 0x0022,
"amp": 0x0026,
"apos": 0x0027,
"lt": 0x003C,
"gt": 0x003E,
"nbsp": 0x00A0,
"iexcl": 0x00A1,
"cent": 0x00A2,
"pound": 0x00A3,
"curren": 0x00A4,
"yen": 0x00A5,
"brvbar": 0x00A6,
"sect": 0x00A7,
"uml": 0x00A8,
"copy": 0x00A9,
"ordf": 0x00AA,
"laquo": 0x00AB,
"not": 0x00AC,
"shy": 0x00AD,
"reg": 0x00AE,
"macr": 0x00AF,
"deg": 0x00B0,
"plusmn": 0x00B1,
"sup2": 0x00B2,
"sup3": 0x00B3,
"acute": 0x00B4,
"micro": 0x00B5,
"para": 0x00B6,
"middot": 0x00B7,
"cedil": 0x00B8,
"sup1": 0x00B9,
"ordm": 0x00BA,
"raquo": 0x00BB,
"frac14": 0x00BC,
"frac12": 0x00BD,
"frac34": 0x00BE,
"iquest": 0x00BF,
"Agrave": 0x00C0,
"Aacute": 0x00C1,
"Acirc": 0x00C2,
"Atilde": 0x00C3,
"Auml": 0x00C4,
"Aring": 0x00C5,
"AElig": 0x00C6,
"Ccedil": 0x00C7,
"Egrave": 0x00C8,
"Eacute": 0x00C9,
"Ecirc": 0x00CA,
"Euml": 0x00CB,
"Igrave": 0x00CC,
"Iacute": 0x00CD,
"Icirc": 0x00CE,
"Iuml": 0x00CF,
"ETH": 0x00D0,
"Ntilde": 0x00D1,
"Ograve": 0x00D2,
"Oacute": 0x00D3,
"Ocirc": 0x00D4,
"Otilde": 0x00D5,
"Ouml": 0x00D6,
"times": 0x00D7,
"Oslash": 0x00D8,
"Ugrave": 0x00D9,
"Uacute": 0x00DA,
"Ucirc": 0x00DB,
"Uuml": 0x00DC,
"Yacute": 0x00DD,
"THORN": 0x00DE,
"szlig": 0x00DF,
"agrave": 0x00E0,
"aacute": 0x00E1,
"acirc": 0x00E2,
"atilde": 0x00E3,
"auml": 0x00E4,
"aring": 0x00E5,
"aelig": 0x00E6,
"ccedil": 0x00E7,
"egrave": 0x00E8,
"eacute": 0x00E9,
"ecirc": 0x00EA,
"euml": 0x00EB,
"igrave": 0x00EC,
"iacute": 0x00ED,
"icirc": 0x00EE,
"iuml": 0x00EF,
"eth": 0x00F0,
"ntilde": 0x00F1,
"ograve": 0x00F2,
"oacute": 0x00F3,
"ocirc": 0x00F4,
"otilde": 0x00F5,
"ouml": 0x00F6,
"divide": 0x00F7,
"oslash": 0x00F8,
"ugrave": 0x00F9,
"uacute": 0x00FA,
"ucirc": 0x00FB,
"uuml": 0x00FC,
"yacute": 0x00FD,
"thorn": 0x00FE,
"yuml": 0x00FF,
"OElig": 0x0152,
"oelig": 0x0153,
"Scaron": 0x0160,
"scaron": 0x0161,
"Yuml": 0x0178,
"fnof": 0x0192,
"circ": 0x02C6,
"tilde": 0x02DC,
"Alpha": 0x0391,
"Beta": 0x0392,
"Gamma": 0x0393,
"Delta": 0x0394,
"Epsilon": 0x0395,
"Zeta": 0x0396,
"Eta": 0x0397,
"Theta": 0x0398,
"Iota": 0x0399,
"Kappa": 0x039A,
"Lambda": 0x039B,
"Mu": 0x039C,
"Nu": 0x039D,
"Xi": 0x039E,
"Omicron": 0x039F,
"Pi": 0x03A0,
"Rho": 0x03A1,
"Sigma": 0x03A3,
"Tau": 0x03A4,
"Upsilon": 0x03A5,
"Phi": 0x03A6,
"Chi": 0x03A7,
"Psi": 0x03A8,
"Omega": 0x03A9,
"alpha": 0x03B1,
"beta": 0x03B2,
"gamma": 0x03B3,
"delta": 0x03B4,
"epsilon": 0x03B5,
"zeta": 0x03B6,
"eta": 0x03B7,
"theta": 0x03B8,
"iota": 0x03B9,
"kappa": 0x03BA,
"lambda": 0x03BB,
"mu": 0x03BC,
"nu": 0x03BD,
"xi": 0x03BE,
"omicron": 0x03BF,
"pi": 0x03C0,
"rho": 0x03C1,
"sigmaf": 0x03C2,
"sigma": 0x03C3,
"tau": 0x03C4,
"upsilon": 0x03C5,
"phi": 0x03C6,
"chi": 0x03C7,
"psi": 0x03C8,
"omega": 0x03C9,
"thetasym": 0x03D1,
"upsih": 0x03D2,
"piv": 0x03D6,
"ensp": 0x2002,
"emsp": 0x2003,
"thinsp": 0x2009,
"zwnj": 0x200C,
"zwj": 0x200D,
"lrm": 0x200E,
"rlm": 0x200F,
"ndash": 0x2013,
"mdash": 0x2014,
"lsquo": 0x2018,
"rsquo": 0x2019,
"sbquo": 0x201A,
"ldquo": 0x201C,
"rdquo": 0x201D,
"bdquo": 0x201E,
"dagger": 0x2020,
"Dagger": 0x2021,
"bull": 0x2022,
"hellip": 0x2026,
"permil": 0x2030,
"prime": 0x2032,
"Prime": 0x2033,
"lsaquo": 0x2039,
"rsaquo": 0x203A,
"oline": 0x203E,
"frasl": 0x2044,
"euro": 0x20AC,
"image": 0x2111,
"weierp": 0x2118,
"real": 0x211C,
"trade": 0x2122,
"alefsym": 0x2135,
"larr": 0x2190,
"uarr": 0x2191,
"rarr": 0x2192,
"darr": 0x2193,
"harr": 0x2194,
"crarr": 0x21B5,
"lArr": 0x21D0,
"uArr": 0x21D1,
"rArr": 0x21D2,
"dArr": 0x21D3,
"hArr": 0x21D4,
"forall": 0x2200,
"part": 0x2202,
"exist": 0x2203,
"empty": 0x2205,
"nabla": 0x2207,
"isin": 0x2208,
"notin": 0x2209,
"ni": 0x220B,
"prod": 0x220F,
"sum": 0x2211,
"minus": 0x2212,
"lowast": 0x2217,
"radic": 0x221A,
"prop": 0x221D,
"infin": 0x221E,
"ang": 0x2220,
"and": 0x2227,
"or": 0x2228,
"cap": 0x2229,
"cup": 0x222A,
"int": 0x222B,
"there4": 0x2234,
"sim": 0x223C,
"cong": 0x2245,
"asymp": 0x2248,
"ne": 0x2260,
"equiv": 0x2261,
"le": 0x2264,
"ge": 0x2265,
"sub": 0x2282,
"sup": 0x2283,
"nsub": 0x2284,
"sube": 0x2286,
"supe": 0x2287,
"oplus": 0x2295,
"otimes": 0x2297,
"perp": 0x22A5,
"sdot": 0x22C5,
"lceil": 0x2308,
"rceil": 0x2309,
"lfloor": 0x230A,
"rfloor": 0x230B,
"lang": 0x2329,
"rang": 0x232A,
"loz": 0x25CA,
"spades": 0x2660,
"clubs": 0x2663,
"hearts": 0x2665,
"diams": 0x2666
};
}
}
+13
View File
@@ -0,0 +1,13 @@
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/*@internal*/
namespace ts {
export function transformES6Module(context: TransformationContext) {
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
return node;
}
}
}
+759
View File
@@ -0,0 +1,759 @@
/// <reference path="../../factory.ts" />
/// <reference path="../../visitor.ts" />
/*@internal*/
namespace ts {
export function transformModule(context: TransformationContext) {
const transformModuleDelegates: Map<(node: SourceFile) => SourceFile> = {
[ModuleKind.None]: transformCommonJSModule,
[ModuleKind.CommonJS]: transformCommonJSModule,
[ModuleKind.AMD]: transformAMDModule,
[ModuleKind.UMD]: transformUMDModule,
};
const {
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
setNodeEmitFlags
} = context;
const compilerOptions = context.getCompilerOptions();
const resolver = context.getEmitResolver();
const languageVersion = getEmitScriptTarget(compilerOptions);
const moduleKind = getEmitModuleKind(compilerOptions);
const previousExpressionSubstitution = context.expressionSubstitution;
context.enableExpressionSubstitution(SyntaxKind.Identifier);
context.expressionSubstitution = substituteExpression;
let currentSourceFile: SourceFile;
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
let exportSpecifiers: Map<ExportSpecifier[]>;
let exportEquals: ExportAssignment;
let hasExportStars: boolean;
return transformSourceFile;
/**
* Transforms the module aspects of a SourceFile.
*
* @param node The SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
// Collect information about the external module.
({ externalImports, exportSpecifiers, exportEquals, hasExportStars } = collectExternalModuleInfo(node, resolver));
// Perform the transformation.
const updated = transformModuleDelegates[moduleKind](node);
currentSourceFile = undefined;
externalImports = undefined;
exportSpecifiers = undefined;
exportEquals = undefined;
hasExportStars = false;
return updated;
}
return node;
}
/**
* Transforms a SourceFile into a CommonJS module.
*
* @param node The SourceFile node.
*/
function transformCommonJSModule(node: SourceFile) {
startLexicalEnvironment();
return setNodeEmitFlags(
updateSourceFile(
node,
[
...visitNodes(node.statements, visitor, isStatement),
...(endLexicalEnvironment() || []),
tryCreateExportEquals(/*emitAsReturn*/ false)
]
),
hasExportStars ? NodeEmitFlags.EmitExportStar : 0
);
}
/**
* Transforms a SourceFile into an AMD module.
*
* @param node The SourceFile node.
*/
function transformAMDModule(node: SourceFile) {
const define = createIdentifier("define");
const moduleName = node.moduleName ? createLiteral(node.moduleName) : undefined;
return transformAsynchronousModule(node, define, moduleName, /*includeNonAmdDependencies*/ true);
}
/**
* Transforms a SourceFile into a UMD module.
*
* @param node The SourceFile node.
*/
function transformUMDModule(node: SourceFile) {
const define = createIdentifier("define");
setNodeEmitFlags(define, NodeEmitFlags.UMDDefine);
return transformAsynchronousModule(node, define, /*moduleName*/ undefined, /*includeNonAmdDependencies*/ false);
}
/**
* Transforms a SourceFile into an AMD or UMD module.
*
* @param node The SourceFile node.
* @param define The expression used to define the module.
* @param moduleName An expression for the module name, if available.
* @param includeNonAmdDependencies A value indicating whether to incldue any non-AMD dependencies.
*/
function transformAsynchronousModule(node: SourceFile, define: Expression, moduleName: Expression, includeNonAmdDependencies: boolean) {
// Start the lexical environment for the module body.
startLexicalEnvironment();
const { importModuleNames, importAliasNames } = collectAsynchronousDependencies(node, includeNonAmdDependencies);
// Create an updated SourceFile:
//
// define(moduleName?, ["module1", "module2"], function ...
return updateSourceFile(node, [
createStatement(
createCall(
define,
flatten([
// Add the module name (if provided).
moduleName,
// Add the dependency array argument:
//
// ["module1", "module2", ...]
createArrayLiteral(importModuleNames),
// Add the module body function argument:
//
// function (module1, module2) ...
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
importAliasNames,
setNodeEmitFlags(
setMultiLine(
createBlock(
flatten([
// Visit each statement of the module body.
...visitNodes(node.statements, visitor, isStatement),
// End the lexical environment for the module body
// and merge any new lexical declarations.
...(endLexicalEnvironment() || []),
// Append the 'export =' statement if provided.
tryCreateExportEquals(/*emitAsReturn*/ true)
])
),
/*multiLine*/ true
),
// If we have any `export * from ...` declarations
// we need to inform the emitter to add the __export helper.
hasExportStars ? NodeEmitFlags.EmitExportStar : 0
)
)
])
)
)
]);
}
function tryCreateExportEquals(emitAsReturn: boolean) {
if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) {
if (emitAsReturn) {
return createReturn(exportEquals.expression);
}
else {
return createStatement(
createAssignment(
createPropertyAccess(
createIdentifier("module"),
"exports"
),
exportEquals.expression
)
);
}
}
return undefined;
}
/**
* Visits a node at the top level of the source file.
*
* @param node The node.
*/
function visitor(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return visitImportDeclaration(<ImportDeclaration>node);
case SyntaxKind.ImportEqualsDeclaration:
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
case SyntaxKind.ExportDeclaration:
return visitExportDeclaration(<ExportDeclaration>node);
case SyntaxKind.ExportAssignment:
return visitExportAssignment(<ExportAssignment>node);
case SyntaxKind.VariableStatement:
return visitVariableStatement(<VariableStatement>node);
case SyntaxKind.FunctionDeclaration:
return visitFunctionDeclaration(<FunctionDeclaration>node);
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(<ClassDeclaration>node);
default:
// This visitor does not descend into the tree, as export/import statements
// are only transformed at the top level of a file.
return node;
}
}
/**
* Visits an ImportDeclaration node.
*
* @param node The ImportDeclaration node.
*/
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
if (!contains(externalImports, node)) {
return undefined;
}
const statements: Statement[] = [];
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (moduleKind !== ModuleKind.AMD) {
if (!node.importClause) {
// import "mod";
addNode(statements,
createStatement(
createRequireCall(node),
/*location*/ node
)
);
}
else {
const variables: VariableDeclaration[] = [];
if (namespaceDeclaration && !isDefaultImport(node)) {
// import * as n from "mod";
addNode(variables,
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
createRequireCall(node)
)
);
}
else {
// import d from "mod";
// import { x, y } from "mod";
// import d, { x, y } from "mod";
// import d, * as n from "mod";
addNode(variables,
createVariableDeclaration(
getGeneratedNameForNode(node),
createRequireCall(node)
)
);
if (namespaceDeclaration && isDefaultImport(node)) {
addNode(variables,
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
getGeneratedNameForNode(node)
)
);
}
}
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(variables),
/*location*/ node
)
);
}
}
else if (namespaceDeclaration && isDefaultImport(node)) {
// import d, * as n from "mod";
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
getGeneratedNameForNode(node),
/*location*/ node
)
])
)
);
}
addExportImportAssignments(statements, node);
return statements;
}
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
if (!contains(externalImports, node)) {
return undefined;
}
const statements: Statement[] = [];
if (moduleKind !== ModuleKind.AMD) {
if (hasModifier(node, ModifierFlags.Export)) {
addNode(statements,
createStatement(
createExportAssignment(
node.name,
createRequireCall(node)
),
/*location*/ node
)
);
}
else {
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
getSynthesizedClone(node.name),
createRequireCall(node),
/*location*/ node
)
])
)
);
}
}
else {
if (hasModifier(node, ModifierFlags.Export)) {
addNode(statements,
createStatement(
createExportAssignment(node.name, node.name),
/*location*/ node
)
);
}
}
addExportImportAssignments(statements, node);
return statements;
}
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
if (!contains(externalImports, node)) {
return undefined;
}
const generatedName = getGeneratedNameForNode(node);
if (node.exportClause) {
const statements: Statement[] = [];
// export { x, y } from "mod";
if (moduleKind !== ModuleKind.AMD) {
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
generatedName,
createRequireCall(node),
/*location*/ node
)
])
)
);
}
for (const specifier of node.exportClause.elements) {
if (resolver.isValueAliasDeclaration(specifier)) {
const exportedValue = createPropertyAccess(
generatedName,
specifier.propertyName || specifier.name
);
addNode(statements,
createStatement(
createExportAssignment(specifier.name, exportedValue),
/*location*/ specifier
)
);
}
}
return statements;
}
else {
// export * from "mod";
return createStatement(
createCall(
createIdentifier("__export"),
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
: generatedName
]
),
/*location*/ node
);
}
}
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
const statements: Statement[] = [];
addExportDefault(statements, node.expression, /*location*/ node);
return statements;
}
return undefined;
}
function addExportDefault(statements: Statement[], expression: Expression, location: TextRange): void {
addNode(statements, tryCreateExportDefaultCompat());
addNode(statements,
createStatement(
createExportAssignment(
createIdentifier("default"),
expression
),
location
)
);
}
function tryCreateExportDefaultCompat(): Statement {
const original = getOriginalNode(currentSourceFile);
Debug.assert(original.kind === SyntaxKind.SourceFile);
if (!(<SourceFile>original).symbol.exports["___esModule"]) {
if (languageVersion === ScriptTarget.ES3) {
return createStatement(
createExportAssignment(
createIdentifier("__esModule"),
createLiteral(true)
)
);
}
else {
return createStatement(
createObjectDefineProperty(
createIdentifier("exports"),
createLiteral("_esModule"),
{ value: createLiteral(true) }
)
);
}
}
}
function addExportImportAssignments(statements: Statement[], node: Node) {
const names = reduceEachChild(node, collectExportMembers, []);
for (const name of names) {
addExportMemberAssignments(statements, name);
}
}
function collectExportMembers(names: Identifier[], node: Node): Identifier[] {
if (isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node) && isDeclaration(node)) {
const name = node.name;
if (isIdentifier(name)) {
names.push(name);
}
}
return reduceEachChild(node, collectExportMembers, names);
}
function addExportMemberAssignments(statements: Statement[], name: Identifier): void {
if (!exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, name.text)) {
for (const specifier of exportSpecifiers[name.text]) {
addNode(statements,
createStatement(
createExportAssignment(specifier.name, name),
/*location*/ specifier.name
)
);
}
}
}
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
const variables = getInitializedVariables(node.declarationList);
if (variables.length === 0) {
// elide statement if there are no initialized variables
return undefined;
}
return createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
)
);
}
function transformInitializedVariable(node: VariableDeclaration): Expression {
const name = node.name;
if (isBindingPattern(name)) {
return flattenVariableDestructuringToExpression(
node,
hoistVariableDeclaration,
getModuleMemberName,
visitor
);
}
else {
return createAssignment(
getModuleMemberName(name),
visitNode(node.initializer, visitor, isExpression)
);
}
}
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
const statements: Statement[] = [];
if (node.name) {
if (hasModifier(node, ModifierFlags.Export)) {
addNode(statements,
createFunctionDeclaration(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
node.name,
node.parameters,
node.body,
/*location*/ node
)
);
if (hasModifier(node, ModifierFlags.Default)) {
addExportDefault(statements, getSynthesizedClone(node.name), /*location*/ node);
}
}
else {
addNode(statements, node);
}
addExportMemberAssignments(statements, node.name);
}
else {
Debug.assert(hasModifier(node, ModifierFlags.Default));
addExportDefault(statements,
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
node.parameters,
node.body,
/*location*/ node
),
/*location*/ node
);
}
return statements;
}
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
const statements: Statement[] = [];
if (node.name) {
if (hasModifier(node, ModifierFlags.Export)) {
addNode(statements,
createClassDeclaration(
/*modifiers*/ undefined,
node.name,
node.heritageClauses,
node.members,
/*location*/ node
)
);
if (hasModifier(node, ModifierFlags.Default)) {
addExportDefault(statements, getSynthesizedClone(node.name), /*location*/ node);
}
}
else {
addNode(statements, node);
}
addExportMemberAssignments(statements, node.name);
}
else {
Debug.assert(hasModifier(node, ModifierFlags.Default));
addExportDefault(statements,
createClassExpression(
/*name*/ undefined,
node.heritageClauses,
node.members,
/*location*/ node
),
/*location*/ node
);
}
return statements;
}
function substituteExpression(node: Expression) {
node = previousExpressionSubstitution(node);
if (isIdentifier(node)) {
return substituteExpressionIdentifier(node);
}
return node;
}
function substituteExpressionIdentifier(node: Identifier): Expression {
const container = resolver.getReferencedExportContainer(node);
if (container && container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
/*location*/ node
);
}
return node;
}
function getModuleMemberName(name: Identifier) {
return createPropertyAccess(
createIdentifier("exports"),
name,
/*location*/ name
);
}
function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) {
const moduleName = getExternalModuleName(importNode);
if (moduleName.kind === SyntaxKind.StringLiteral) {
return tryRenameExternalModule(<StringLiteral>moduleName)
|| getSynthesizedClone(<StringLiteral>moduleName);
}
return undefined;
}
/**
* Some bundlers (SystemJS builder) sometimes want to rename dependencies.
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
function tryRenameExternalModule(moduleName: LiteralExpression) {
if (currentSourceFile.renamedDependencies && hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) {
return createLiteral(currentSourceFile.renamedDependencies[moduleName.text]);
}
return undefined;
}
function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): Identifier {
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
return createIdentifier(getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name));
}
if (node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).importClause) {
return getGeneratedNameForNode(node);
}
if (node.kind === SyntaxKind.ExportDeclaration && (<ExportDeclaration>node).moduleSpecifier) {
return getGeneratedNameForNode(node);
}
}
function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
const moduleName = getExternalModuleNameLiteral(importNode);
Debug.assert(isDefined(moduleName));
return createCall(
createIdentifier("require"),
[moduleName]
);
}
function createExportAssignment(name: Identifier, value: Expression) {
return createAssignment(
name.originalKeywordKind && languageVersion === ScriptTarget.ES3
? createElementAccess(
createIdentifier("exports"),
createLiteral(name.text)
)
: createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(name)
),
value
);
}
function collectAsynchronousDependencies(node: SourceFile, includeNonAmdDependencies: boolean) {
// An AMD define function has the following shape:
//
// define(id?, dependencies?, factory);
//
// This has the shape of the following:
//
// define(name, ["module1", "module2"], function (module1Alias) { ... }
//
// The location of the alias in the parameter list in the factory function needs to
// match the position of the module name in the dependency list.
//
// To ensure this is true in cases of modules with no aliases, e.g.:
//
// import "module"
//
// or
//
// /// <amd-dependency path= "a.css" />
//
// we need to add modules without alias names to the end of the dependencies list
const unaliasedModuleNames: Expression[] = [];
const aliasedModuleNames: Expression[] = [createLiteral("require"), createLiteral("exports") ];
const importAliasNames = [createParameter("require"), createParameter("exports")];
for (const amdDependency of node.amdDependencies) {
if (amdDependency.name) {
aliasedModuleNames.push(createLiteral(amdDependency.name));
importAliasNames.push(createParameter(createIdentifier(amdDependency.name)));
}
else {
unaliasedModuleNames.push(createLiteral(amdDependency.path));
}
}
for (const importNode of externalImports) {
// Find the name of the external module
const externalModuleName = getExternalModuleNameLiteral(importNode);
// Find the name of the module alias, if there is one
const importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
aliasedModuleNames.push(externalModuleName);
importAliasNames.push(createParameter(importAliasName));
}
else {
unaliasedModuleNames.push(externalModuleName);
}
}
return {
importModuleNames: [
...unaliasedModuleNames,
...aliasedModuleNames
],
importAliasNames
};
}
function updateSourceFile(node: SourceFile, statements: Statement[]) {
const updated = getMutableClone(node);
updated.statements = createNodeArray(statements, node.statements);
return updated;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4
View File
@@ -777,4 +777,8 @@ namespace ts {
}
}
if (ts.sys.developmentMode && ts.sys.tryEnableSourceMapsForHost) {
ts.sys.tryEnableSourceMapsForHost();
}
ts.executeCommandLine(ts.sys.args);
+6
View File
@@ -17,6 +17,12 @@
"utilities.ts",
"binder.ts",
"checker.ts",
"factory.ts",
"visitor.ts",
"transformer.ts",
"comments.ts",
"printer.ts",
"declarationEmitter.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
+204 -35
View File
@@ -20,6 +20,7 @@ namespace ts {
export interface TextRange {
pos: number;
end: number;
/* @internal */ disableSourceMap?: boolean; // Whether a synthesized text range disables source maps for its contents (used by transforms).
}
// token > SyntaxKind.Identifer => token is a keyword
@@ -341,6 +342,7 @@ namespace ts {
// Synthesized list
SyntaxList,
// Enum value count
Count,
// Markers
@@ -371,18 +373,9 @@ namespace ts {
export const enum NodeFlags {
None = 0,
Export = 1 << 0, // Declarations
Ambient = 1 << 1, // Declarations
Public = 1 << 2, // Property/Method
Private = 1 << 3, // Property/Method
Protected = 1 << 4, // Property/Method
Static = 1 << 5, // Property/Method
Readonly = 1 << 6, // Property/Method
Abstract = 1 << 7, // Class/Method/ConstructSignature
Async = 1 << 8, // Property/Method/Function
Default = 1 << 9, // Function/Class (export default declaration)
Let = 1 << 10, // Variable declaration
Const = 1 << 11, // Variable declaration
Let = 1 << 0, // Variable declaration
Const = 1 << 1, // Variable declaration
NestedNamespace = 1 << 2, // Namespace declaration
Namespace = 1 << 12, // Namespace declaration
ExportContext = 1 << 13, // Export context (initialized by binding)
ContainsThis = 1 << 14, // Interface contains references to "this"
@@ -402,8 +395,6 @@ namespace ts {
ThisNodeOrAnySubNodesHasError = 1 << 28, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 29, // If we've computed data from children and cached it in this node
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
AccessibilityModifier = Public | Private | Protected,
BlockScoped = Let | Const,
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
@@ -416,6 +407,26 @@ namespace ts {
TypeExcludesFlags = YieldContext | AwaitContext,
}
export const enum ModifierFlags {
None = 0,
Export = 1 << 0, // Declarations
Ambient = 1 << 1, // Declarations
Public = 1 << 2, // Property/Method
Private = 1 << 3, // Property/Method
Protected = 1 << 4, // Property/Method
Static = 1 << 5, // Property/Method
Readonly = 1 << 6, // Property/Method
Abstract = 1 << 7, // Class/Method/ConstructSignature
Async = 1 << 8, // Property/Method/Function
Default = 1 << 9, // Function/Class (export default declaration)
Const = 1 << 11, // Variable declaration
HasComputedFlags = 1 << 31, // Modifier flags have been computed
AccessibilityModifier = Public | Private | Protected,
NonPublicAccessibilityModifier = Private | Protected,
}
export const enum JsxFlags {
None = 0,
/** An element from a named property of the JSX.IntrinsicElements interface */
@@ -441,10 +452,15 @@ namespace ts {
export interface Node extends TextRange {
kind: SyntaxKind;
flags: NodeFlags;
/* @internal */ modifierFlagsCache?: ModifierFlags;
/* @internal */ transformFlags?: TransformFlags;
/* @internal */ excludeTransformFlags?: TransformFlags;
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
modifiers?: ModifiersArray; // Array of modifiers
modifiers?: NodeArray<Modifier>; // Array of modifiers
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
parent?: Node; // Parent node (initialized by binding
parent?: Node; // Parent node (initialized by binding)
/* @internal */ original?: Node; // The original node if this is an updated node.
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
/* @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)
@@ -452,14 +468,10 @@ namespace ts {
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
}
export interface NodeArray<T> extends Array<T>, TextRange {
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
hasTrailingComma?: boolean;
}
export interface ModifiersArray extends NodeArray<Modifier> {
flags: number;
}
// @kind(SyntaxKind.AbstractKeyword)
// @kind(SyntaxKind.AsyncKeyword)
// @kind(SyntaxKind.ConstKeyword)
@@ -472,10 +484,19 @@ namespace ts {
// @kind(SyntaxKind.StaticKeyword)
export interface Modifier extends Node { }
export const enum GeneratedIdentifierKind {
None, // Not automatically generated.
Auto, // Automatically generated identifier.
Loop, // Automatically generated identifier with a preference for '_i'.
Unique, // Unique name based on the 'text' property.
Node, // Unique name based on the node in the 'original' property.
}
// @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
}
// @kind(SyntaxKind.QualifiedName)
@@ -532,10 +553,12 @@ namespace ts {
// @kind(SyntaxKind.ConstructSignature)
export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement { }
export type BindingName = Identifier | ObjectBindingPattern | ArrayBindingPattern;
// @kind(SyntaxKind.VariableDeclaration)
export interface VariableDeclaration extends Declaration {
parent?: VariableDeclarationList;
name: Identifier | BindingPattern; // Declared variable name
name: BindingName; // Declared variable name
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
}
@@ -548,7 +571,7 @@ namespace ts {
// @kind(SyntaxKind.Parameter)
export interface ParameterDeclaration extends Declaration {
dotDotDotToken?: Node; // Present on rest parameter
name: Identifier | BindingPattern; // Declared parameter name
name: BindingName; // Declared parameter name
questionToken?: Node; // Present on optional parameter
type?: TypeNode; // Optional type annotation
initializer?: Expression; // Optional initializer
@@ -558,7 +581,7 @@ namespace ts {
export interface BindingElement extends Declaration {
propertyName?: PropertyName; // Binding property name (in object binding pattern)
dotDotDotToken?: Node; // Present on rest binding element
name: Identifier | BindingPattern; // Declared binding element name
name: BindingName; // Declared binding element name
initializer?: Expression; // Optional initializer
}
@@ -925,6 +948,8 @@ namespace ts {
_templateLiteralFragmentBrand: any;
}
export type Template = TemplateExpression | LiteralExpression;
// @kind(SyntaxKind.TemplateExpression)
export interface TemplateExpression extends PrimaryExpression {
head: TemplateLiteralFragment;
@@ -996,7 +1021,7 @@ namespace ts {
// @kind(SyntaxKind.TaggedTemplateExpression)
export interface TaggedTemplateExpression extends MemberExpression {
tag: LeftHandSideExpression;
template: LiteralExpression | TemplateExpression;
template: Template;
}
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
@@ -1028,7 +1053,7 @@ namespace ts {
export interface JsxOpeningElement extends Expression {
_openingElementBrand?: any;
tagName: EntityName;
attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>;
attributes: NodeArray<JsxAttributeLike>;
}
/// A JSX expression of the form <TagName attrs />
@@ -1040,6 +1065,8 @@ namespace ts {
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
// @kind(SyntaxKind.JsxAttribute)
export interface JsxAttribute extends Node {
name: Identifier;
@@ -1089,6 +1116,7 @@ namespace ts {
// @kind(SyntaxKind.Block)
export interface Block extends Statement {
statements: NodeArray<Statement>;
/*@internal*/ multiLine?: boolean;
}
// @kind(SyntaxKind.VariableStatement)
@@ -1122,22 +1150,24 @@ namespace ts {
expression: Expression;
}
export type ForInitializer = VariableDeclarationList | Expression;
// @kind(SyntaxKind.ForStatement)
export interface ForStatement extends IterationStatement {
initializer?: VariableDeclarationList | Expression;
initializer?: ForInitializer;
condition?: Expression;
incrementor?: Expression;
}
// @kind(SyntaxKind.ForInStatement)
export interface ForInStatement extends IterationStatement {
initializer: VariableDeclarationList | Expression;
initializer: ForInitializer;
expression: Expression;
}
// @kind(SyntaxKind.ForOfStatement)
export interface ForOfStatement extends IterationStatement {
initializer: VariableDeclarationList | Expression;
initializer: ForInitializer;
expression: Expression;
}
@@ -1264,7 +1294,7 @@ namespace ts {
export interface EnumMember extends Declaration {
// This does include ComputedPropertyName, but the parser will give an error
// if it parses a ComputedPropertyName in an EnumMember
name: DeclarationName;
name: PropertyName;
initializer?: Expression;
}
@@ -1276,9 +1306,11 @@ namespace ts {
export type ModuleBody = ModuleBlock | ModuleDeclaration;
export type ModuleName = Identifier | StringLiteral;
// @kind(SyntaxKind.ModuleDeclaration)
export interface ModuleDeclaration extends DeclarationStatement {
name: Identifier | LiteralExpression;
name: ModuleName;
body: ModuleBlock | ModuleDeclaration;
}
@@ -1287,13 +1319,15 @@ namespace ts {
statements: NodeArray<Statement>;
}
export type ModuleReference = EntityName | ExternalModuleReference;
// @kind(SyntaxKind.ImportEqualsDeclaration)
export interface ImportEqualsDeclaration extends DeclarationStatement {
name: Identifier;
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
// module reference.
moduleReference: EntityName | ExternalModuleReference;
moduleReference: ModuleReference;
}
// @kind(SyntaxKind.ExternalModuleReference)
@@ -1311,6 +1345,8 @@ namespace ts {
moduleSpecifier: Expression;
}
export type NamedImportBindings = NamespaceImport | NamedImports;
// In case of:
// import d from "mod" => name = d, namedBinding = undefined
// import * as ns from "mod" => name = undefined, namedBinding: NamespaceImport = { name: ns }
@@ -1320,7 +1356,7 @@ namespace ts {
// @kind(SyntaxKind.ImportClause)
export interface ImportClause extends Declaration {
name?: Identifier; // Default binding
namedBindings?: NamespaceImport | NamedImports;
namedBindings?: NamedImportBindings;
}
// @kind(SyntaxKind.NamespaceImport)
@@ -2042,8 +2078,8 @@ namespace ts {
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
HasSeenSuperCall = 0x00080000, // Set during the binding when encounter 'super'
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
DecoratedClassWithSelfReference = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
SelfReferenceInDecoratedClass = 0x00200000, // Binding to a decorated class inside of the class's body.
}
/* @internal */
@@ -2423,6 +2459,7 @@ namespace ts {
allowSyntheticDefaultImports?: boolean;
allowJs?: boolean;
/* @internal */ stripInternal?: boolean;
/* @internal */ experimentalTransforms?: boolean;
// Skip checking lib.d.ts to help speed up tests.
/* @internal */ skipDefaultLibCheck?: boolean;
@@ -2699,6 +2736,138 @@ namespace ts {
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
}
/* @internal */
export const enum TransformFlags {
None = 0,
// Facts
// - Flags used to indicate that a node or subtree contains syntax that requires transformation.
TypeScript = 1 << 0,
ContainsTypeScript = 1 << 1,
Jsx = 1 << 2,
ContainsJsx = 1 << 3,
ES7 = 1 << 4,
ContainsES7 = 1 << 5,
ES6 = 1 << 6,
ContainsES6 = 1 << 7,
DestructuringAssignment = 1 << 8,
// Markers
// - Flags used to indicate that a subtree contains a specific transformation.
ContainsDecorators = 1 << 9,
ContainsPropertyInitializer = 1 << 10,
ContainsLexicalThis = 1 << 11,
ContainsCapturedLexicalThis = 1 << 12,
ContainsDefaultValueAssignments = 1 << 13,
ContainsParameterPropertyAssignments = 1 << 14,
ContainsSpreadElementExpression = 1 << 15,
ContainsComputedPropertyName = 1 << 16,
ContainsBlockScopedBinding = 1 << 17,
HasComputedFlags = 1 << 31, // Transform flags have been computed.
// Assertions
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
AssertTypeScript = TypeScript | ContainsTypeScript,
AssertJsx = Jsx | ContainsJsx,
AssertES7 = ES7 | ContainsES7,
AssertES6 = ES6 | ContainsES6,
// Scope Exclusions
// - Bitmasks that exclude flags from propagating out of a specific context
// into the subtree flags of their container.
NodeExcludes = TypeScript | Jsx | ES7 | ES6 | DestructuringAssignment | HasComputedFlags,
ArrowFunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
FunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
ConstructorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
MethodOrAccessorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
ClassExcludes = ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments,
ModuleExcludes = ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
TypeExcludes = ~ContainsTypeScript,
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName,
ArrayLiteralOrCallOrNewExcludes = ContainsSpreadElementExpression,
}
/* @internal */
export const enum NodeEmitFlags {
EmitEmitHelpers = 1 << 0, // Any emit helpers should be written to this node.
EmitExportStar = 1 << 1, // The export * helper should be written to this node.
EmitSuperHelper = 1 << 2, // Emit the basic _super helper for async methods.
EmitAdvancedSuperHelper = 1 << 3, // Emit the advanced _super helper for async methods.
UMDDefine = 1 << 4, // This node should be replaced with the UMD define helper.
NoLexicalEnvironment = 1 << 5, // A new LexicalEnvironment should *not* be introduced when emitting this node, this is primarily used when printing a SystemJS module.
SingleLine = 1 << 6, // The contents of this node should be emit on a single line.
AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node.
IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible.
EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes.
NoSubstitution = 1 << 10, // Disables further substitution of an expression.
CapturesThis = 1 << 11, // The function captures a lexical `this`
}
/** Additional context provided to `visitEachChild` */
export interface LexicalEnvironment {
/** Starts a new lexical environment. */
startLexicalEnvironment(): void;
/** Ends a lexical environment, returning any declarations. */
endLexicalEnvironment(): Statement[];
}
/* @internal */
export interface TransformationContext extends LexicalEnvironment {
getCompilerOptions(): CompilerOptions;
getEmitResolver(): EmitResolver;
getNodeEmitFlags(node: Node): NodeEmitFlags;
setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags): T;
hoistFunctionDeclaration(node: FunctionDeclaration): void;
hoistVariableDeclaration(node: Identifier): void;
/**
* Hook used by transformers to substitute non-expression identifiers
* just before theyare emitted by the pretty printer.
*/
identifierSubstitution?: (node: Identifier) => Identifier;
/**
* Enables expression substitutions in the pretty printer for
* the provided SyntaxKind.
*/
enableExpressionSubstitution(kind: SyntaxKind): void;
/**
* Determines whether expression substitutions are enabled for the
* provided node.
*/
isExpressionSubstitutionEnabled(node: Node): boolean;
/**
* Hook used by transformers to substitute expressions just before they
* are emitted by the pretty printer.
*/
expressionSubstitution?: (node: Expression) => Expression;
/**
* Enables before/after emit notifications in the pretty printer for
* the provided SyntaxKind.
*/
enableEmitNotification(kind: SyntaxKind): void;
/**
* Determines whether before/after emit notifications should be raised
* in the pretty printer when it emits a node.
*/
isEmitNotificationEnabled(node: Node): boolean;
/**
* Hook used to allow transformers to capture state before or after
* the printer emits a node.
*/
onEmitNode?: (node: Node, emit: (node: Node) => void) => void;
}
/* @internal */
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
export interface TextSpan {
start: number;
length: number;
+1139 -252
View File
File diff suppressed because it is too large Load Diff
+956
View File
@@ -0,0 +1,956 @@
/// <reference path="checker.ts" />
/// <reference path="factory.ts" />
/* @internal */
namespace ts {
export type VisitResult<T extends Node> = T | T[];
/**
* Describes an edge of a Node, used when traversing a syntax tree.
*/
interface NodeEdge {
/** The property name for the edge. */
name: string;
/** Indicates that the result is optional. */
optional?: boolean;
/** A callback used to test whether a node is valid. */
test?: (node: Node) => node is Node;
/** A callback used to lift a NodeArrayNode into a valid node. */
lift?: (nodes: NodeArray<Node>) => Node;
/** A callback used to parenthesize a node to preserve the intended order of operations. */
parenthesize?: (value: Node, parentNode: Node) => Node;
};
/**
* Describes the shape of a Node.
*/
type NodeTraversalPath = NodeEdge[];
/**
* This map contains information about the shape of each Node in "types.ts" pertaining to how
* each node should be traversed during a transformation.
*
* Each edge corresponds to a property in a Node subtype that should be traversed when visiting
* each child. The properties are assigned in the order in which traversal should occur.
*
* NOTE: This needs to be kept up to date with changes to nodes in "types.ts". Currently, this
* map is not comprehensive. Only node edges relevant to tree transformation are
* currently defined. We may extend this to be more comprehensive, and eventually
* supplant the existing `forEachChild` implementation if performance is not
* significantly impacted.
*/
const nodeEdgeTraversalMap: Map<NodeTraversalPath> = {
[SyntaxKind.QualifiedName]: [
{ name: "left", test: isEntityName },
{ name: "right", test: isIdentifier },
],
[SyntaxKind.ComputedPropertyName]: [
{ name: "expression", test: isExpression },
],
[SyntaxKind.Parameter]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isBindingName },
{ name: "type", test: isTypeNode, optional: true },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.Decorator]: [
{ name: "expression", test: isLeftHandSideExpression },
],
[SyntaxKind.PropertyDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isPropertyName },
{ name: "type", test: isTypeNode, optional: true },
{ name: "initializer", test: isExpression, optional: true },
],
[SyntaxKind.MethodDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isPropertyName },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.Constructor]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.GetAccessor]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isPropertyName },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.SetAccessor]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isPropertyName },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.ObjectBindingPattern]: [
{ name: "elements", test: isBindingElement },
],
[SyntaxKind.ArrayBindingPattern]: [
{ name: "elements", test: isBindingElement },
],
[SyntaxKind.BindingElement]: [
{ name: "propertyName", test: isPropertyName, optional: true },
{ name: "name", test: isBindingName },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.ArrayLiteralExpression]: [
{ name: "elements", test: isExpression, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.ObjectLiteralExpression]: [
{ name: "properties", test: isObjectLiteralElement },
],
[SyntaxKind.PropertyAccessExpression]: [
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
{ name: "name", test: isIdentifier },
],
[SyntaxKind.ElementAccessExpression]: [
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
{ name: "argumentExpression", test: isExpression },
],
[SyntaxKind.CallExpression]: [
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
{ name: "typeArguments", test: isTypeNode },
{ name: "arguments", test: isExpression },
],
[SyntaxKind.NewExpression]: [
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForNew },
{ name: "typeArguments", test: isTypeNode },
{ name: "arguments", test: isExpression },
],
[SyntaxKind.TaggedTemplateExpression]: [
{ name: "tag", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
{ name: "template", test: isTemplate },
],
[SyntaxKind.TypeAssertionExpression]: [
{ name: "type", test: isTypeNode },
{ name: "expression", test: isUnaryExpression },
],
[SyntaxKind.ParenthesizedExpression]: [
{ name: "expression", test: isExpression },
],
[SyntaxKind.FunctionExpression]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier, optional: true },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.ArrowFunction]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isConciseBody, lift: liftToBlock, parenthesize: parenthesizeConciseBody },
],
[SyntaxKind.DeleteExpression]: [
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
],
[SyntaxKind.TypeOfExpression]: [
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
],
[SyntaxKind.VoidExpression]: [
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
],
[SyntaxKind.AwaitExpression]: [
{ name: "expression", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
],
[SyntaxKind.PrefixUnaryExpression]: [
{ name: "operand", test: isUnaryExpression, parenthesize: parenthesizePrefixOperand },
],
[SyntaxKind.PostfixUnaryExpression]: [
{ name: "operand", test: isLeftHandSideExpression, parenthesize: parenthesizePostfixOperand },
],
[SyntaxKind.BinaryExpression]: [
{ name: "left", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, true) },
{ name: "right", test: isExpression, parenthesize: (node: Expression, parent: BinaryExpression) => parenthesizeBinaryOperand(getOperator(parent), node, false) },
],
[SyntaxKind.ConditionalExpression]: [
{ name: "condition", test: isExpression },
{ name: "whenTrue", test: isExpression },
{ name: "whenFalse", test: isExpression },
],
[SyntaxKind.TemplateExpression]: [
{ name: "head", test: isTemplateLiteralFragment },
{ name: "templateSpans", test: isTemplateSpan },
],
[SyntaxKind.YieldExpression]: [
{ name: "expression", test: isExpression, optional: true },
],
[SyntaxKind.SpreadElementExpression]: [
{ name: "expression", test: isExpression, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.ClassExpression]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier, optional: true },
{ name: "typeParameters", test: isTypeParameter },
{ name: "heritageClauses", test: isHeritageClause },
{ name: "members", test: isClassElement },
],
[SyntaxKind.ExpressionWithTypeArguments]: [
{ name: "expression", test: isLeftHandSideExpression, parenthesize: parenthesizeForAccess },
{ name: "typeArguments", test: isTypeNode },
],
[SyntaxKind.AsExpression]: [
{ name: "expression", test: isExpression },
{ name: "type", test: isTypeNode },
],
[SyntaxKind.TemplateSpan]: [
{ name: "expression", test: isExpression },
{ name: "literal", test: isTemplateLiteralFragment },
],
[SyntaxKind.Block]: [
{ name: "statements", test: isStatement },
],
[SyntaxKind.VariableStatement]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "declarationList", test: isVariableDeclarationList },
],
[SyntaxKind.ExpressionStatement]: [
{ name: "expression", test: isExpression, parenthesize: parenthesizeExpressionForExpressionStatement },
],
[SyntaxKind.IfStatement]: [
{ name: "expression", test: isExpression },
{ name: "thenStatement", test: isStatement, lift: liftToBlock },
{ name: "elseStatement", test: isStatement, lift: liftToBlock, optional: true },
],
[SyntaxKind.DoStatement]: [
{ name: "statement", test: isStatement, lift: liftToBlock },
{ name: "expression", test: isExpression },
],
[SyntaxKind.WhileStatement]: [
{ name: "expression", test: isExpression },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.ForStatement]: [
{ name: "initializer", test: isForInitializer, optional: true },
{ name: "condition", test: isExpression, optional: true },
{ name: "incrementor", test: isExpression, optional: true },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.ForInStatement]: [
{ name: "initializer", test: isForInitializer },
{ name: "expression", test: isExpression },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.ForOfStatement]: [
{ name: "initializer", test: isForInitializer },
{ name: "expression", test: isExpression },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.ContinueStatement]: [
{ name: "label", test: isIdentifier, optional: true },
],
[SyntaxKind.BreakStatement]: [
{ name: "label", test: isIdentifier, optional: true },
],
[SyntaxKind.ReturnStatement]: [
{ name: "expression", test: isExpression, optional: true },
],
[SyntaxKind.WithStatement]: [
{ name: "expression", test: isExpression },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.SwitchStatement]: [
{ name: "expression", test: isExpression },
{ name: "caseBlock", test: isCaseBlock },
],
[SyntaxKind.LabeledStatement]: [
{ name: "label", test: isIdentifier },
{ name: "statement", test: isStatement, lift: liftToBlock },
],
[SyntaxKind.ThrowStatement]: [
{ name: "expression", test: isExpression },
],
[SyntaxKind.TryStatement]: [
{ name: "tryBlock", test: isBlock },
{ name: "catchClause", test: isCatchClause, optional: true },
{ name: "finallyBlock", test: isBlock, optional: true },
],
[SyntaxKind.VariableDeclaration]: [
{ name: "name", test: isBindingName },
{ name: "type", test: isTypeNode, optional: true },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.VariableDeclarationList]: [
{ name: "declarations", test: isVariableDeclaration },
],
[SyntaxKind.FunctionDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier, optional: true },
{ name: "typeParameters", test: isTypeParameter },
{ name: "parameters", test: isParameter },
{ name: "type", test: isTypeNode, optional: true },
{ name: "body", test: isBlock, optional: true },
],
[SyntaxKind.ClassDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier, optional: true },
{ name: "typeParameters", test: isTypeParameter },
{ name: "heritageClauses", test: isHeritageClause },
{ name: "members", test: isClassElement },
],
[SyntaxKind.EnumDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier },
{ name: "members", test: isEnumMember },
],
[SyntaxKind.ModuleDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isModuleName },
{ name: "body", test: isModuleBody },
],
[SyntaxKind.ModuleBlock]: [
{ name: "statements", test: isStatement },
],
[SyntaxKind.CaseBlock]: [
{ name: "clauses", test: isCaseOrDefaultClause },
],
[SyntaxKind.ImportEqualsDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "name", test: isIdentifier },
{ name: "moduleReference", test: isModuleReference },
],
[SyntaxKind.ImportDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "importClause", test: isImportClause, optional: true },
{ name: "moduleSpecifier", test: isExpression },
],
[SyntaxKind.ImportClause]: [
{ name: "name", test: isIdentifier, optional: true },
{ name: "namedBindings", test: isNamedImportBindings, optional: true },
],
[SyntaxKind.NamespaceImport]: [
{ name: "name", test: isIdentifier },
],
[SyntaxKind.NamedImports]: [
{ name: "elements", test: isImportSpecifier },
],
[SyntaxKind.ImportSpecifier]: [
{ name: "propertyName", test: isIdentifier, optional: true },
{ name: "name", test: isIdentifier },
],
[SyntaxKind.ExportAssignment]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "expression", test: isExpression },
],
[SyntaxKind.ExportDeclaration]: [
{ name: "decorators", test: isDecorator },
{ name: "modifiers", test: isModifier },
{ name: "exportClause", test: isNamedExports, optional: true },
{ name: "moduleSpecifier", test: isExpression, optional: true },
],
[SyntaxKind.NamedExports]: [
{ name: "elements", test: isExportSpecifier },
],
[SyntaxKind.ExportSpecifier]: [
{ name: "propertyName", test: isIdentifier, optional: true },
{ name: "name", test: isIdentifier },
],
[SyntaxKind.ExternalModuleReference]: [
{ name: "expression", test: isExpression, optional: true },
],
[SyntaxKind.JsxElement]: [
{ name: "openingElement", test: isJsxOpeningElement },
{ name: "children", test: isJsxChild },
{ name: "closingElement", test: isJsxClosingElement },
],
[SyntaxKind.JsxSelfClosingElement]: [
{ name: "tagName", test: isEntityName },
{ name: "attributes", test: isJsxAttributeLike },
],
[SyntaxKind.JsxOpeningElement]: [
{ name: "tagName", test: isEntityName },
{ name: "attributes", test: isJsxAttributeLike },
],
[SyntaxKind.JsxClosingElement]: [
{ name: "tagName", test: isEntityName },
],
[SyntaxKind.JsxAttribute]: [
{ name: "name", test: isIdentifier },
{ name: "initializer", test: isExpression, optional: true },
],
[SyntaxKind.JsxSpreadAttribute]: [
{ name: "expression", test: isExpression },
],
[SyntaxKind.JsxExpression]: [
{ name: "expression", test: isExpression, optional: true },
],
[SyntaxKind.CaseClause]: [
{ name: "expression", test: isExpression, parenthesize: parenthesizeExpressionForList },
{ name: "statements", test: isStatement },
],
[SyntaxKind.DefaultClause]: [
{ name: "statements", test: isStatement },
],
[SyntaxKind.HeritageClause]: [
{ name: "types", test: isExpressionWithTypeArguments },
],
[SyntaxKind.CatchClause]: [
{ name: "variableDeclaration", test: isVariableDeclaration },
{ name: "block", test: isBlock },
],
[SyntaxKind.PropertyAssignment]: [
{ name: "name", test: isPropertyName },
{ name: "initializer", test: isExpression, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.ShorthandPropertyAssignment]: [
{ name: "name", test: isIdentifier },
{ name: "objectAssignmentInitializer", test: isExpression, optional: true },
],
[SyntaxKind.EnumMember]: [
{ name: "name", test: isPropertyName },
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList },
],
[SyntaxKind.SourceFile]: [
{ name: "statements", test: isStatement },
],
};
/**
* Similar to `reduceLeft`, performs a reduction against each child of a node.
* NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the
* `nodeEdgeTraversalMap` above will be visited.
*
* @param node The node containing the children to reduce.
* @param f The callback function
* @param initial The initial value to supply to the reduction.
*/
export function reduceEachChild<T>(node: Node, f: (memo: T, node: Node) => T, initial: T): T {
if (node === undefined) {
return undefined;
}
let result = initial;
const edgeTraversalPath = nodeEdgeTraversalMap[node.kind];
if (edgeTraversalPath) {
for (const edge of edgeTraversalPath) {
const value = (<Map<any>>node)[edge.name];
if (value !== undefined) {
result = isArray(value)
? reduceLeft(<NodeArray<Node>>value, f, result)
: f(result, <Node>value);
}
}
}
return result;
}
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param optional An optional value indicating whether the Node is itself optional.
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
*/
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
return <T>visitNodeWorker(node, visitor, test, optional, lift, /*parenthesize*/ undefined, /*parentNode*/ undefined);
}
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
*
* @param node The Node to visit.
* @param visitor The callback used to visit the Node.
* @param test A callback to execute to verify the Node is valid.
* @param optional A value indicating whether the Node is itself optional.
* @param lift A callback to execute to lift a NodeArrayNode into a valid Node.
* @param parenthesize A callback used to parenthesize the node if needed.
* @param parentNode A parentNode for the node.
*/
function visitNodeWorker(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: Node[]) => Node, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): Node {
if (node === undefined) {
return undefined;
}
const visited = visitor(node);
if (visited === node) {
return node;
}
let visitedNode: Node;
if (visited === undefined) {
if (!optional) {
Debug.failNotOptional();
}
return undefined;
}
else if (isArray(visited)) {
visitedNode = (lift || extractSingleNode)(visited);
}
else {
visitedNode = visited;
}
if (parenthesize !== undefined) {
visitedNode = parenthesize(visitedNode, parentNode);
}
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
return visitedNode;
}
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
export function visitNodes<T extends Node, TArray extends NodeArray<T>>(nodes: TArray, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): TArray {
return <TArray>visitNodesWorker(nodes, visitor, test, /*parenthesize*/ undefined, /*parentNode*/ undefined, start, count);
}
/**
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
*
* @param nodes The NodeArray to visit.
* @param visitor The callback used to visit a Node.
* @param test A node test to execute for each node.
* @param start An optional value indicating the starting offset at which to start visiting.
* @param count An optional value indicating the maximum number of nodes to visit.
*/
function visitNodesWorker(nodes: NodeArray<Node>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, start: number, count: number): NodeArray<Node> {
if (nodes === undefined) {
return undefined;
}
let updated: NodeArray<Node>;
// Ensure start and count have valid values
const length = nodes.length;
if (start === undefined || start < 0) {
start = 0;
}
if (count === undefined || count > length - start) {
count = length - start;
}
if (start > 0 || count < length) {
// If we are not visiting all of the original nodes, we must always create a new array.
// Since this is a fragment of a node array, we do not copy over the previous location
// and will only copy over `hasTrailingComma` if we are including the last element.
updated = createNodeArray<Node>([], /*location*/ undefined,
/*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
}
// Visit each original node.
for (let i = 0; i < count; i++) {
const node = nodes[i + start];
const visited = node !== undefined ? visitor(node) : undefined;
if (updated !== undefined || visited === undefined || visited !== node) {
if (updated === undefined) {
// Ensure we have a copy of `nodes`, up to the current index.
updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma);
}
addNodeWorker(updated, visited, /*addOnNewLine*/ undefined, test, parenthesize, parentNode, /*isVisiting*/ visited !== node);
}
}
return updated || nodes;
}
/**
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
*
* @param node The Node whose children will be visited.
* @param visitor The callback used to visit each child.
* @param context A lexical environment context for the visitor.
*/
export function visitEachChild<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T;
export function visitEachChild<T extends Node>(node: T & Map<any>, visitor: (node: Node) => VisitResult<Node>, context: LexicalEnvironment): T {
if (node === undefined) {
return undefined;
}
let updated: T & Map<any>;
// If this node starts a new lexical environment, start a new lexical environment on the context.
const isNewLexicalEnvironment = nodeStartsNewLexicalEnvironment(node);
if (isNewLexicalEnvironment) {
context.startLexicalEnvironment();
}
const edgeTraversalPath = nodeEdgeTraversalMap[node.kind];
if (edgeTraversalPath) {
for (const edge of edgeTraversalPath) {
const value = <Node | NodeArray<Node>>node[edge.name];
if (value !== undefined) {
let visited: Node | NodeArray<Node>;
if (isArray(value)) {
const visitedArray = visitNodesWorker(value, visitor, edge.test, edge.parenthesize, node, 0, value.length);
visited = visitedArray;
}
else {
visited = visitNodeWorker(<Node>value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node);
}
if (updated !== undefined || visited !== value) {
if (updated === undefined) {
updated = getMutableClone(node);
}
if (visited !== value) {
updated[edge.name] = visited;
}
}
}
}
}
if (updated === undefined) {
updated = node;
}
if (isNewLexicalEnvironment) {
const declarations = context.endLexicalEnvironment();
if (declarations !== undefined && declarations.length > 0) {
updated = <T>mergeLexicalEnvironment(updated, declarations);
}
}
if (updated !== node) {
aggregateTransformFlags(updated);
updated.original = node;
}
return updated;
}
/**
* Appends a node to an array.
*
* @param to The destination array.
* @param from The source Node or NodeArrayNode.
*/
export function addNode<T extends Node>(to: T[], from: VisitResult<T>, startOnNewLine?: boolean): void {
addNodeWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
}
/**
* Appends an array of nodes to an array.
*
* @param to The destination NodeArray.
* @param from The source array of Node or NodeArrayNode.
*/
export function addNodes<T extends Node>(to: T[], from: VisitResult<T>[], startOnNewLine?: boolean): void {
addNodesWorker(to, from, startOnNewLine, /*test*/ undefined, /*parenthesize*/ undefined, /*parentNode*/ undefined, /*isVisiting*/ false);
}
function addNodeWorker(to: Node[], from: VisitResult<Node>, startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void {
if (to && from) {
if (isArray(from)) {
addNodesWorker(to, from, startOnNewLine, test, parenthesize, parentNode, isVisiting);
}
else {
const node = parenthesize !== undefined
? parenthesize(from, parentNode)
: from;
Debug.assertNode(node, test);
if (startOnNewLine) {
node.startsOnNewLine = true;
}
if (isVisiting) {
aggregateTransformFlags(node);
}
to.push(node);
}
}
}
function addNodesWorker(to: Node[], from: VisitResult<Node>[], startOnNewLine: boolean, test: (node: Node) => boolean, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node, isVisiting: boolean): void {
if (to && from) {
for (const node of from) {
addNodeWorker(to, node, startOnNewLine, test, parenthesize, parentNode, isVisiting);
}
}
}
/**
* Merge generated declarations of a lexical environment.
*
* @param node The source node.
* @param declarations The generated lexical declarations.
*/
function mergeLexicalEnvironment(node: Node, declarations: Statement[]): Node {
switch (node.kind) {
case SyntaxKind.SourceFile:
return mergeSourceFileLexicalEnvironment(<SourceFile>node, declarations);
case SyntaxKind.ModuleDeclaration:
return mergeModuleDeclarationLexicalEnvironment(<ModuleDeclaration>node, declarations);
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.Constructor:
case SyntaxKind.ArrowFunction:
return mergeFunctionLikeLexicalEnvironment(<FunctionLikeDeclaration>node, declarations);
}
Debug.fail("Node is not a valid lexical environment.");
}
/**
* Merge generated declarations of a lexical environment into a SourceFile.
*
* @param node The SourceFile node.
* @param declarations The generated lexical declarations.
*/
export function mergeSourceFileLexicalEnvironment(node: SourceFile, declarations: Statement[]): SourceFile {
if (declarations !== undefined && declarations.length) {
const mutableNode = getMutableClone(node);
mutableNode.statements = mergeStatements(mutableNode.statements, declarations);
return mutableNode;
}
return node;
}
/**
* Merge generated declarations of a lexical environment into a ModuleDeclaration.
*
* @param node The ModuleDeclaration node.
* @param declarations The generated lexical declarations.
*/
export function mergeModuleDeclarationLexicalEnvironment(node: ModuleDeclaration, declarations: Statement[]): ModuleDeclaration {
Debug.assert(node.body.kind === SyntaxKind.ModuleBlock);
if (declarations !== undefined && declarations.length) {
const mutableNode = getMutableClone(node);
mutableNode.body = mergeBlockLexicalEnvironment(<ModuleBlock>node.body, declarations);
return mutableNode;
}
return node;
}
/**
* Merge generated declarations of a lexical environment into a FunctionLikeDeclaration.
*
* @param node The function-like node.
* @param declarations The generated lexical declarations.
*/
function mergeFunctionLikeLexicalEnvironment(node: FunctionLikeDeclaration, declarations: Statement[]): FunctionLikeDeclaration {
Debug.assert(node.body !== undefined);
if (declarations !== undefined && declarations.length) {
const mutableNode = getMutableClone(node);
mutableNode.body = mergeConciseBodyLexicalEnvironment(mutableNode.body, declarations);
return mutableNode;
}
return node;
}
/**
* Merges generated lexical declarations into the FunctionBody of a non-arrow function-like declaration.
*
* @param node The ConciseBody of an arrow function.
* @param declarations The lexical declarations to merge.
*/
export function mergeFunctionBodyLexicalEnvironment(body: FunctionBody, declarations: Statement[]): FunctionBody {
if (declarations !== undefined && declarations.length > 0) {
return mergeBlockLexicalEnvironment(body, declarations);
}
return body;
}
/**
* Merges generated lexical declarations into the ConciseBody of an ArrowFunction.
*
* @param node The ConciseBody of an arrow function.
* @param declarations The lexical declarations to merge.
*/
export function mergeConciseBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
if (declarations !== undefined && declarations.length > 0) {
if (isBlock(body)) {
return mergeBlockLexicalEnvironment(body, declarations);
}
else {
return createBlock([
createReturn(body),
...declarations
]);
}
}
return body;
}
/**
* Merge generated declarations of a lexical environment into a FunctionBody or ModuleBlock.
*
* @param node The block into which to merge lexical declarations.
* @param declarations The lexical declarations to merge.
*/
function mergeBlockLexicalEnvironment<T extends Block>(node: T, declarations: Statement[]): T {
const mutableNode = getMutableClone(node);
mutableNode.statements = mergeStatements(node.statements, declarations);
return mutableNode;
}
/**
* Merge generated declarations of a lexical environment into a NodeArray of Statement.
*
* @param statements The node array to concatentate with the supplied lexical declarations.
* @param declarations The lexical declarations to merge.
*/
function mergeStatements(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement> {
return createNodeArray(concatenate(statements, declarations), /*location*/ statements);
}
/**
* Lifts a NodeArray containing only Statement nodes to a block.
*
* @param nodes The NodeArray.
*/
export function liftToBlock(nodes: Node[]): Block {
Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block.");
return createBlock(<NodeArray<Statement>>nodes);
}
/**
* Extracts the single node from a NodeArray.
*
* @param nodes The NodeArray.
*/
function extractSingleNode(nodes: Node[]): Node {
Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
return singleOrUndefined(nodes);
}
/**
* Aggregates the TransformFlags for a Node and its subtree.
*/
export function aggregateTransformFlags(node: Node): void {
aggregateTransformFlagsForNode(node);
}
/**
* Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
* computed first, then the transform flags for the current node are computed from the subtree
* flags and the state of the current node. Finally, the transform flags of the node are
* returned, excluding any flags that should not be included in its parent node's subtree
* flags.
*/
function aggregateTransformFlagsForNode(node: Node): TransformFlags {
if (node === undefined) {
return TransformFlags.None;
}
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
return node.transformFlags & ~node.excludeTransformFlags;
}
else {
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
return computeTransformFlagsForNode(node, subtreeFlags);
}
}
/**
* Aggregates the transform flags for the subtree of a node.
*/
function aggregateTransformFlagsForSubtree(node: Node): TransformFlags {
// We do not transform ambient declarations or types, so there is no need to
// recursively aggregate transform flags.
if (hasModifier(node, ModifierFlags.Ambient) || isTypeNode(node)) {
return TransformFlags.None;
}
// Aggregate the transform flags of each child.
return reduceEachChild(node, aggregateTransformFlagsForChildNode, TransformFlags.None);
}
/**
* Aggregates the TransformFlags of a child node with the TransformFlags of its
* siblings.
*/
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, child: Node): TransformFlags {
return transformFlags | aggregateTransformFlagsForNode(child);
}
export namespace Debug {
export function failNotOptional(message?: string) {
if (shouldAssert(AssertionLevel.Normal)) {
Debug.assert(false, message || "Node not optional.");
}
}
export function failBadSyntaxKind(node: Node, message?: string) {
if (shouldAssert(AssertionLevel.Normal)) {
Debug.assert(false,
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} was unexpected.`);
}
}
export function assertNode<T extends Node>(node: Node, test: (node: Node) => boolean, message?: string): void {
if (shouldAssert(AssertionLevel.Normal)) {
Debug.assert(
test === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`);
};
}
function getFunctionName(func: Function) {
if (typeof func !== "function") {
return "";
}
else if (func.hasOwnProperty("name")) {
return (<any>func).name;
}
else {
const text = Function.prototype.toString.call(func);
const match = /^function\s+([\w\$]+)\s*\(/.exec(text);
return match ? match[1] : "";
}
}
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ class TypeWriterWalker {
}
private visitNode(node: ts.Node): void {
if (ts.isExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
if (ts.isPartOfExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
this.logTypeAndSymbol(node);
}
+58 -58
View File
@@ -1,54 +1,54 @@
/**
* Declaration module describing the TypeScript Server protocol
/**
* Declaration module describing the TypeScript Server protocol
*/
declare namespace ts.server.protocol {
/**
* A TypeScript Server message
/**
* A TypeScript Server message
*/
export interface Message {
/**
* Sequence number of the message
/**
* Sequence number of the message
*/
seq: number;
/**
* One of "request", "response", or "event"
* One of "request", "response", or "event"
*/
type: string;
}
/**
* Client-initiated request message
/**
* Client-initiated request message
*/
export interface Request extends Message {
/**
* The command to execute
* The command to execute
*/
command: string;
/**
* Object containing arguments for the command
/**
* Object containing arguments for the command
*/
arguments?: any;
}
/**
* Request to reload the project structure for all the opened files
* Request to reload the project structure for all the opened files
*/
export interface ReloadProjectsRequest extends Message {
}
/**
* Server-initiated event message
/**
* Server-initiated event message
*/
export interface Event extends Message {
/**
* Name of event
/**
* Name of event
*/
event: string;
/**
* Event-specific information
/**
* Event-specific information
*/
body?: any;
}
@@ -62,18 +62,18 @@ declare namespace ts.server.protocol {
*/
request_seq: number;
/**
* Outcome of the request.
/**
* Outcome of the request.
*/
success: boolean;
/**
/**
* The command requested.
*/
command: string;
/**
* Contains error message if success === false.
/**
* Contains error message if success === false.
*/
message?: string;
@@ -83,7 +83,7 @@ declare namespace ts.server.protocol {
body?: any;
}
/**
/**
* Arguments for FileRequest messages.
*/
export interface FileRequestArgs {
@@ -93,7 +93,7 @@ declare namespace ts.server.protocol {
file: string;
}
/**
/**
* Arguments for ProjectInfoRequest request.
*/
export interface ProjectInfoRequestArgs extends FileRequestArgs {
@@ -110,7 +110,7 @@ declare namespace ts.server.protocol {
arguments: ProjectInfoRequestArgs;
}
/**
/**
* Response message body for "projectInfo" request
*/
export interface ProjectInfo {
@@ -125,7 +125,7 @@ declare namespace ts.server.protocol {
fileNames?: string[];
}
/**
/**
* Response message for "projectInfo" request
*/
export interface ProjectInfoResponse extends Response {
@@ -144,12 +144,12 @@ declare namespace ts.server.protocol {
* (file, line, character offset), where line and character offset are 1-based.
*/
export interface FileLocationRequestArgs extends FileRequestArgs {
/**
/**
* The line number for the request (1-based).
*/
line: number;
/**
/**
* The character offset (on the line) for the request (1-based).
*/
offset: number;
@@ -216,7 +216,7 @@ declare namespace ts.server.protocol {
* Object found in response messages defining a span of text in a specific source file.
*/
export interface FileSpan extends TextSpan {
/**
/**
* File containing text span.
*/
file: string;
@@ -300,14 +300,14 @@ declare namespace ts.server.protocol {
*/
lineText: string;
/**
/**
* True if reference is a write location, false otherwise.
*/
isWriteAccess: boolean;
}
/**
* The body of a "references" response message.
* The body of a "references" response message.
*/
export interface ReferencesResponseBody {
/**
@@ -325,7 +325,7 @@ declare namespace ts.server.protocol {
*/
symbolStartOffset: number;
/**
/**
* The full display name of the symbol.
*/
symbolDisplayString: string;
@@ -355,7 +355,7 @@ declare namespace ts.server.protocol {
}
/**
* Information about the item to be renamed.
* Information about the item to be renamed.
*/
export interface RenameInfo {
/**
@@ -373,7 +373,7 @@ declare namespace ts.server.protocol {
*/
displayName: string;
/**
/**
* Full display name of item to be renamed.
*/
fullDisplayName: string;
@@ -383,7 +383,7 @@ declare namespace ts.server.protocol {
*/
kind: string;
/**
/**
* Optional modifiers for the kind (such as 'public').
*/
kindModifiers: string;
@@ -469,7 +469,7 @@ declare namespace ts.server.protocol {
placeOpenBraceOnNewLineForControlBlocks?: boolean;
/** Index operator */
[key: string] : string | number | boolean;
[key: string]: string | number | boolean;
}
/**
@@ -477,7 +477,7 @@ declare namespace ts.server.protocol {
*/
export interface ConfigureRequestArguments {
/**
/**
* Information about the host, for example 'Emacs 24.4' or
* 'Sublime Text version 3075'
*/
@@ -495,7 +495,7 @@ declare namespace ts.server.protocol {
}
/**
* Configure request; value of command field is "configure". Specifies
* Configure request; value of command field is "configure". Specifies
* host information, such as host type, tab size, and indent size.
*/
export interface ConfigureRequest extends Request {
@@ -514,8 +514,8 @@ declare namespace ts.server.protocol {
*/
export interface OpenRequestArgs extends FileRequestArgs {
/**
* Used when a version of the file content is known to be more up to date than the one on disk.
* Then the known content will be used upon opening instead of the disk copy
* Used when a version of the file content is known to be more up to date than the one on disk.
* Then the known content will be used upon opening instead of the disk copy
*/
fileContent?: string;
}
@@ -751,7 +751,7 @@ declare namespace ts.server.protocol {
* Optional modifiers for the kind (such as 'public').
*/
kindModifiers: string;
/**
/**
* A string that is used for comparing completion items so that they can be ordered. This
* is often the same as the name but may be different in certain circumstances.
*/
@@ -794,7 +794,7 @@ declare namespace ts.server.protocol {
}
/**
* Signature help information for a single parameter
* Signature help information for a single parameter
*/
export interface SignatureHelpParameter {
@@ -814,18 +814,18 @@ declare namespace ts.server.protocol {
displayParts: SymbolDisplayPart[];
/**
* Whether the parameter is optional or not.
* Whether the parameter is optional or not.
*/
isOptional: boolean;
}
/**
* Represents a single signature to show in signature help.
* Represents a single signature to show in signature help.
*/
export interface SignatureHelpItem {
/**
* Whether the signature accepts a variable number of arguments.
* Whether the signature accepts a variable number of arguments.
*/
isVariadic: boolean;
@@ -845,7 +845,7 @@ declare namespace ts.server.protocol {
separatorDisplayParts: SymbolDisplayPart[];
/**
* The signature helps items for the parameters.
* The signature helps items for the parameters.
*/
parameters: SignatureHelpParameter[];
@@ -861,17 +861,17 @@ declare namespace ts.server.protocol {
export interface SignatureHelpItems {
/**
* The signature help items.
* The signature help items.
*/
items: SignatureHelpItem[];
/**
* The span for which signature help should appear on a signature
* The span for which signature help should appear on a signature
*/
applicableSpan: TextSpan;
/**
* The item selected in the set of available help items.
* The item selected in the set of available help items.
*/
selectedItemIndex: number;
@@ -895,7 +895,7 @@ declare namespace ts.server.protocol {
/**
* Signature help request; value of command field is "signatureHelp".
* Given a file location (file, line, col), return the signature
* Given a file location (file, line, col), return the signature
* help.
*/
export interface SignatureHelpRequest extends FileLocationRequest {
@@ -926,8 +926,8 @@ declare namespace ts.server.protocol {
}
/**
* GeterrForProjectRequest request; value of command field is
* "geterrForProject". It works similarly with 'Geterr', only
* GeterrForProjectRequest request; value of command field is
* "geterrForProject". It works similarly with 'Geterr', only
* it request for every file in this project.
*/
export interface GeterrForProjectRequest extends Request {
@@ -997,7 +997,7 @@ declare namespace ts.server.protocol {
diagnostics: Diagnostic[];
}
/**
/**
* Event message for "syntaxDiag" and "semanticDiag" event types.
* These events provide syntactic and semantic errors for a file.
*/
@@ -1033,7 +1033,7 @@ declare namespace ts.server.protocol {
export interface ReloadResponse extends Response {
}
/**
/**
* Arguments for saveto request.
*/
export interface SavetoRequestArgs extends FileRequestArgs {
@@ -1109,7 +1109,7 @@ declare namespace ts.server.protocol {
*/
kindModifiers?: string;
/**
/**
* The file in which the symbol is found.
*/
file: string;
@@ -1156,7 +1156,7 @@ declare namespace ts.server.protocol {
/**
* Change request message; value of command field is "change".
* Update the server's view of the file named by argument 'file'.
* Update the server's view of the file named by argument 'file'.
* Server does not currently send a response to a change request.
*/
export interface ChangeRequest extends FileLocationRequest {
+22 -22
View File
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// See LICENSE.txt in the project root for complete license information.
/// <reference path='services.ts' />
@@ -19,8 +19,8 @@ namespace ts.BreakpointResolver {
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
// Get previous token if the token is returned starts on new line
// eg: let x =10; |--- cursor is here
// let y = 10;
// token at position will return let keyword on second line as the token but we would like to use
// let y = 10;
// token at position will return let keyword on second line as the token but we would like to use
// token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile);
@@ -56,7 +56,7 @@ namespace ts.BreakpointResolver {
return spanInNode(otherwiseOnNode);
}
function spanInNodeArray<T>(nodeArray: NodeArray<T>) {
function spanInNodeArray<T extends Node>(nodeArray: NodeArray<T>) {
return createTextSpanFromBounds(skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
}
@@ -259,13 +259,13 @@ namespace ts.BreakpointResolver {
if (isArrayLiteralOrObjectLiteralDestructuringPattern(node)) {
return spanInArrayLiteralOrObjectLiteralDestructuringPattern(<DestructuringPattern>node);
}
// Set breakpoint on identifier element of destructuring pattern
// a or ...c or d: x from
// a or ...c or d: x from
// [a, b, ...c] or { a, b } or { d: x } from destructuring pattern
if ((node.kind === SyntaxKind.Identifier ||
node.kind == SyntaxKind.SpreadElementExpression ||
node.kind === SyntaxKind.PropertyAssignment ||
node.kind == SyntaxKind.SpreadElementExpression ||
node.kind === SyntaxKind.PropertyAssignment ||
node.kind === SyntaxKind.ShorthandPropertyAssignment) &&
isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
return textSpan(node);
@@ -275,7 +275,7 @@ namespace ts.BreakpointResolver {
const binaryExpression = <BinaryExpression>node;
// Set breakpoint in destructuring pattern if its destructuring assignment
// [a, b, c] or {a, b, c} of
// [a, b, c] = expression or
// [a, b, c] = expression or
// {a, b, c} = expression
if (isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) {
return spanInArrayLiteralOrObjectLiteralDestructuringPattern(
@@ -285,8 +285,8 @@ namespace ts.BreakpointResolver {
if (binaryExpression.operatorToken.kind === SyntaxKind.EqualsToken &&
isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) {
// Set breakpoint on assignment expression element of destructuring pattern
// a = expression of
// [a = expression, b, c] = someExpression or
// a = expression of
// [a = expression, b, c] = someExpression or
// { a = expression, b, c } = someExpression
return textSpan(node);
}
@@ -296,7 +296,7 @@ namespace ts.BreakpointResolver {
}
}
if (isExpression(node)) {
if (isPartOfExpression(node)) {
switch (node.parent.kind) {
case SyntaxKind.DoStatement:
// Set span as if on while keyword
@@ -325,14 +325,14 @@ namespace ts.BreakpointResolver {
break;
}
}
// If this is name of property assignment, set breakpoint in the initializer
if (node.parent.kind === SyntaxKind.PropertyAssignment &&
(<PropertyDeclaration>node.parent).name === node &&
(<PropertyDeclaration>node.parent).name === node &&
!isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
return spanInNode((<PropertyDeclaration>node.parent).initializer);
}
// Breakpoint in type assertion goes to its operand
if (node.parent.kind === SyntaxKind.TypeAssertionExpression && (<TypeAssertion>node.parent).type === node) {
return spanInNextNode((<TypeAssertion>node.parent).type);
@@ -386,7 +386,7 @@ namespace ts.BreakpointResolver {
if (variableDeclaration.parent.parent.kind === SyntaxKind.ForInStatement) {
return spanInNode(variableDeclaration.parent.parent);
}
// If this is a destructuring pattern set breakpoint in binding pattern
if (isBindingPattern(variableDeclaration.name)) {
return spanInBindingPattern(<BindingPattern>variableDeclaration.name);
@@ -395,7 +395,7 @@ namespace ts.BreakpointResolver {
// Breakpoint is possible in variableDeclaration only if there is initialization
// or its declaration from 'for of'
if (variableDeclaration.initializer ||
(variableDeclaration.flags & NodeFlags.Export) ||
hasModifier(variableDeclaration, ModifierFlags.Export) ||
variableDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
return textSpanFromVariableDeclaration(variableDeclaration);
}
@@ -403,7 +403,7 @@ namespace ts.BreakpointResolver {
let declarations = variableDeclaration.parent.declarations;
if (declarations && declarations[0] !== variableDeclaration) {
// If we cant set breakpoint on this declaration, set it on previous one
// Because the variable declaration may be binding pattern and
// Because the variable declaration may be binding pattern and
// we would like to set breakpoint in last binding element if thats the case,
// use preceding token instead
return spanInNode(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
@@ -413,7 +413,7 @@ namespace ts.BreakpointResolver {
function canHaveSpanInParameterDeclaration(parameter: ParameterDeclaration): boolean {
// Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier
return !!parameter.initializer || parameter.dotDotDotToken !== undefined ||
!!(parameter.flags & NodeFlags.Public) || !!(parameter.flags & NodeFlags.Private);
hasModifier(parameter, ModifierFlags.Public | ModifierFlags.Private);
}
function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan {
@@ -439,7 +439,7 @@ namespace ts.BreakpointResolver {
}
function canFunctionHaveSpanInWholeDeclaration(functionDeclaration: FunctionLikeDeclaration) {
return !!(functionDeclaration.flags & NodeFlags.Export) ||
return hasModifier(functionDeclaration, ModifierFlags.Export) ||
(functionDeclaration.parent.kind === SyntaxKind.ClassDeclaration && functionDeclaration.kind !== SyntaxKind.Constructor);
}
@@ -549,7 +549,7 @@ namespace ts.BreakpointResolver {
return spanInNode(firstBindingElement);
}
// Could be ArrayLiteral from destructuring assignment or
// Could be ArrayLiteral from destructuring assignment or
// just nested element in another destructuring assignment
// set breakpoint on assignment when parent is destructuring assignment
// Otherwise set breakpoint for this element
@@ -686,7 +686,7 @@ namespace ts.BreakpointResolver {
function spanInColonToken(node: Node): TextSpan {
// Is this : specifying return annotation of the function declaration
if (isFunctionLike(node.parent) ||
node.parent.kind === SyntaxKind.PropertyAssignment ||
node.parent.kind === SyntaxKind.PropertyAssignment ||
node.parent.kind === SyntaxKind.Parameter) {
return spanInPreviousNode(node);
}
+5 -5
View File
@@ -313,7 +313,7 @@ namespace ts.formatting {
this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space));
this.NoSpaceBetweenReturnAndSemicolon = new Rule(RuleDescriptor.create1(SyntaxKind.ReturnKeyword, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotForContext), RuleAction.Space));
@@ -554,17 +554,17 @@ namespace ts.formatting {
static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean {
//// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction.
////
//// Ex:
//// Ex:
//// if (1) { ....
//// * ) and { are on the same line so apply the rule. Here we don't care whether it's same or multi block context
////
//// Ex:
//// Ex:
//// if (1)
//// { ... }
//// * ) and { are on differnet lines. We only need to format if the block is multiline context. So in this case we don't format.
////
//// Ex:
//// if (1)
//// if (1)
//// { ...
//// }
//// * ) and { are on differnet lines. We only need to format if the block is multiline context. So in this case we format.
@@ -735,7 +735,7 @@ namespace ts.formatting {
}
static NodeIsInDecoratorContext(node: Node): boolean {
while (isExpression(node)) {
while (isPartOfExpression(node)) {
node = node.parent;
}
return node.kind === SyntaxKind.Decorator;
+3 -3
View File
@@ -204,7 +204,7 @@ namespace ts.formatting {
// - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually
// - parent and child are not on the same line
let useActualIndentation =
(isDeclaration(current) || isStatement(current)) &&
(isDeclaration(current) || isStatementButNotDeclaration(current)) &&
(parent.kind === SyntaxKind.SourceFile || !parentAndChildShareLine);
if (!useActualIndentation) {
@@ -467,7 +467,7 @@ namespace ts.formatting {
}
return false;
}
/* @internal */
export function nodeWillIndentChild(parent: TextRangeWithKind, child: TextRangeWithKind, indentByDefault: boolean) {
let childKind = child ? child.kind : SyntaxKind.Unknown;
@@ -497,7 +497,7 @@ namespace ts.formatting {
Function returns true when the parent node should indent the given child by an explicit rule
*/
export function shouldIndentChildNode(parent: TextRangeWithKind, child?: TextRangeWithKind): boolean {
return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false);
return nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, false);
}
}
}
+9 -9
View File
@@ -130,7 +130,7 @@ namespace ts.NavigationBar {
return topLevelNodes;
}
function sortNodes(nodes: Node[]): Node[] {
return nodes.slice(0).sort((n1: Declaration, n2: Declaration) => {
if (n1.name && n2.name) {
@@ -147,7 +147,7 @@ namespace ts.NavigationBar {
}
});
}
function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void {
nodes = sortNodes(nodes);
@@ -178,8 +178,8 @@ namespace ts.NavigationBar {
function isTopLevelFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration) {
if (functionDeclaration.kind === SyntaxKind.FunctionDeclaration) {
// A function declaration is 'top level' if it contains any function declarations
// within it.
// A function declaration is 'top level' if it contains any function declarations
// within it.
if (functionDeclaration.body && functionDeclaration.body.kind === SyntaxKind.Block) {
// Proper function declarations can only have identifier names
if (forEach((<Block>functionDeclaration.body).statements,
@@ -198,7 +198,7 @@ namespace ts.NavigationBar {
return false;
}
function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] {
let items: ts.NavigationBarItem[] = [];
@@ -258,7 +258,7 @@ namespace ts.NavigationBar {
if (isBindingPattern((<ParameterDeclaration>node).name)) {
break;
}
if ((node.flags & NodeFlags.Modifier) === 0) {
if (!hasModifiers(node)) {
return undefined;
}
return createItem(node, getTextOfNode((<ParameterDeclaration>node).name), ts.ScriptElementKind.memberVariableElement);
@@ -395,19 +395,19 @@ namespace ts.NavigationBar {
let result: string[] = [];
result.push(moduleDeclaration.name.text);
while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) {
moduleDeclaration = <ModuleDeclaration>moduleDeclaration.body;
result.push(moduleDeclaration.name.text);
}
}
return result.join(".");
}
function createModuleItem(node: ModuleDeclaration): NavigationBarItem {
let moduleName = getModuleName(node);
let childItems = getItemsWorker(getChildNodes((<Block>getInnermostModule(node).body).statements), createChildItem);
return getNavigationBarItem(moduleName,
+31 -25
View File
@@ -186,6 +186,9 @@ namespace ts {
public end: number;
public flags: NodeFlags;
public parent: Node;
public original: Node;
public transformFlags: TransformFlags;
public excludeTransformFlags: TransformFlags;
private _children: Node[];
constructor(kind: SyntaxKind, pos: number, end: number) {
@@ -193,7 +196,10 @@ namespace ts {
this.pos = pos;
this.end = end;
this.flags = NodeFlags.None;
this.transformFlags = undefined;
this.excludeTransformFlags = undefined;
this.parent = undefined;
this.original = undefined;
}
public getSourceFile(): SourceFile {
@@ -956,7 +962,7 @@ namespace ts {
case SyntaxKind.Parameter:
// Only consider properties defined as constructor parameters
if (!(node.flags & NodeFlags.AccessibilityModifier)) {
if (!(getModifierFlags(node) & ModifierFlags.AccessibilityModifier)) {
break;
}
// fall through
@@ -1876,7 +1882,7 @@ namespace ts {
options.isolatedModules = true;
// transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
// transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.
options.suppressOutputPathCheck = true;
// Filename can be non-ts file.
@@ -2649,7 +2655,7 @@ namespace ts {
case SyntaxKind.Constructor: return ScriptElementKind.constructorImplementationElement;
case SyntaxKind.TypeParameter: return ScriptElementKind.typeParameterElement;
case SyntaxKind.EnumMember: return ScriptElementKind.variableElement;
case SyntaxKind.Parameter: return (node.flags & NodeFlags.AccessibilityModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
case SyntaxKind.Parameter: return (getModifierFlags(node) & ModifierFlags.AccessibilityModifier) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ImportClause:
@@ -2984,7 +2990,7 @@ namespace ts {
// e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid.
// We, thus, need to check if whatever was inside the quotes is actually a valid identifier name.
if (performCharacterChecks) {
if (!isIdentifier(name, target)) {
if (!isIdentifierText(name, target)) {
return undefined;
}
}
@@ -5040,14 +5046,14 @@ namespace ts {
}
const keywords: Node[] = [];
const modifierFlag: NodeFlags = getFlagFromModifier(modifier);
const modifierFlag: ModifierFlags = getFlagFromModifier(modifier);
let nodes: Node[];
switch (container.kind) {
case SyntaxKind.ModuleBlock:
case SyntaxKind.SourceFile:
// Container is either a class declaration or the declaration is a classDeclaration
if (modifierFlag & NodeFlags.Abstract) {
if (modifierFlag & ModifierFlags.Abstract) {
nodes = (<Node[]>(<ClassDeclaration>declaration).members).concat(declaration);
}
else {
@@ -5064,7 +5070,7 @@ namespace ts {
// If we're an accessibility modifier, we're in an instance member and should search
// the constructor's parameter list for instance members as well.
if (modifierFlag & NodeFlags.AccessibilityModifier) {
if (modifierFlag & ModifierFlags.AccessibilityModifier) {
const constructor = forEach((<ClassLikeDeclaration>container).members, member => {
return member.kind === SyntaxKind.Constructor && <ConstructorDeclaration>member;
});
@@ -5073,7 +5079,7 @@ namespace ts {
nodes = nodes.concat(constructor.parameters);
}
}
else if (modifierFlag & NodeFlags.Abstract) {
else if (modifierFlag & ModifierFlags.Abstract) {
nodes = nodes.concat(container);
}
break;
@@ -5082,7 +5088,7 @@ namespace ts {
}
forEach(nodes, node => {
if (node.modifiers && node.flags & modifierFlag) {
if (getModifierFlags(node) & modifierFlag) {
forEach(node.modifiers, child => pushKeywordIf(keywords, child, modifier));
}
});
@@ -5092,19 +5098,19 @@ namespace ts {
function getFlagFromModifier(modifier: SyntaxKind) {
switch (modifier) {
case SyntaxKind.PublicKeyword:
return NodeFlags.Public;
return ModifierFlags.Public;
case SyntaxKind.PrivateKeyword:
return NodeFlags.Private;
return ModifierFlags.Private;
case SyntaxKind.ProtectedKeyword:
return NodeFlags.Protected;
return ModifierFlags.Protected;
case SyntaxKind.StaticKeyword:
return NodeFlags.Static;
return ModifierFlags.Static;
case SyntaxKind.ExportKeyword:
return NodeFlags.Export;
return ModifierFlags.Export;
case SyntaxKind.DeclareKeyword:
return NodeFlags.Ambient;
return ModifierFlags.Ambient;
case SyntaxKind.AbstractKeyword:
return NodeFlags.Abstract;
return ModifierFlags.Abstract;
default:
Debug.fail();
}
@@ -5558,7 +5564,7 @@ namespace ts {
// If this is private property or method, the scope is the containing class
if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) {
const privateDeclaration = forEach(symbol.getDeclarations(), d => (d.flags & NodeFlags.Private) ? d : undefined);
const privateDeclaration = forEach(symbol.getDeclarations(), d => (getModifierFlags(d) & ModifierFlags.Private) ? d : undefined);
if (privateDeclaration) {
return getAncestor(privateDeclaration, SyntaxKind.ClassDeclaration);
}
@@ -5813,7 +5819,7 @@ namespace ts {
return undefined;
}
// Whether 'super' occurs in a static context within a class.
let staticFlag = NodeFlags.Static;
let staticFlag = ModifierFlags.Static;
switch (searchSpaceNode.kind) {
case SyntaxKind.PropertyDeclaration:
@@ -5823,7 +5829,7 @@ namespace ts {
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
staticFlag &= searchSpaceNode.flags;
staticFlag &= getModifierFlags(searchSpaceNode);
searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
break;
default:
@@ -5848,7 +5854,7 @@ namespace ts {
// If we have a 'super' container, we must have an enclosing class.
// Now make sure the owning class is the same as the search-space
// and has the same static qualifier as the original 'super's owner.
if (container && (NodeFlags.Static & container.flags) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
if (container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
references.push(getReferenceEntryFromNode(node));
}
});
@@ -5861,7 +5867,7 @@ namespace ts {
let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
// Whether 'this' occurs in a static context within a class.
let staticFlag = NodeFlags.Static;
let staticFlag = ModifierFlags.Static;
switch (searchSpaceNode.kind) {
case SyntaxKind.MethodDeclaration:
@@ -5875,7 +5881,7 @@ namespace ts {
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
staticFlag &= searchSpaceNode.flags;
staticFlag &= getModifierFlags(searchSpaceNode);
searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class
break;
case SyntaxKind.SourceFile:
@@ -5947,7 +5953,7 @@ namespace ts {
case SyntaxKind.ClassDeclaration:
// Make sure the container belongs to the same class
// and has the appropriate static modifier from the original container.
if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (container.flags & NodeFlags.Static) === staticFlag) {
if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (getModifierFlags(container) & ModifierFlags.Static) === staticFlag) {
result.push(getReferenceEntryFromNode(node));
}
break;
@@ -6102,7 +6108,7 @@ namespace ts {
}
}
// For export specifiers, it can be a local symbol, e.g.
// For export specifiers, it can be a local symbol, e.g.
// import {a} from "mod";
// export {a as somethingElse}
// We want the local target of the export (i.e. the import symbol) and not the final target (i.e. "mod".a)
@@ -6340,7 +6346,7 @@ namespace ts {
return node.parent.kind === SyntaxKind.TypeReference ||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
(node.kind === SyntaxKind.ThisKeyword && !isExpression(node)) ||
(node.kind === SyntaxKind.ThisKeyword && !isPartOfExpression(node)) ||
node.kind === SyntaxKind.ThisType;
}
+9 -9
View File
@@ -521,15 +521,15 @@ namespace ts {
}
export function getNodeModifiers(node: Node): string {
let flags = getCombinedNodeFlags(node);
let flags = getCombinedModifierFlags(node);
let result: string[] = [];
if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier);
if (flags & NodeFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier);
if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier);
if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & NodeFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier);
if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
if (flags & ModifierFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier);
if (flags & ModifierFlags.Protected) result.push(ScriptElementKindModifier.protectedMemberModifier);
if (flags & ModifierFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier);
if (flags & ModifierFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & ModifierFlags.Abstract) result.push(ScriptElementKindModifier.abstractModifier);
if (flags & ModifierFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier);
return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none;
@@ -615,7 +615,7 @@ namespace ts {
// [a,b,c] from:
// [a, b, c] = someExpression;
if (node.parent.kind === SyntaxKind.BinaryExpression &&
(<BinaryExpression>node.parent).left === node &&
(<BinaryExpression>node.parent).left === node &&
(<BinaryExpression>node.parent).operatorToken.kind === SyntaxKind.EqualsToken) {
return true;
}
@@ -629,7 +629,7 @@ namespace ts {
// [a, b, c] of
// [x, [a, b, c] ] = someExpression
// or
// or
// {x, a: {a, b, c} } = someExpression
if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.kind === SyntaxKind.PropertyAssignment ? node.parent.parent : node.parent)) {
return true;
@@ -28,9 +28,9 @@ var Point = (function () {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
var Point;
(function (Point) {
Point.Origin = ""; //expected duplicate identifier error
@@ -42,9 +42,9 @@ var A;
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
A.Point = Point;
var Point;
(function (Point) {
@@ -28,9 +28,9 @@ var Point = (function () {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
var Point;
(function (Point) {
var Origin = ""; // not an error, since not exported
@@ -42,9 +42,9 @@ var A;
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
A.Point = Point;
var Point;
(function (Point) {
@@ -7,6 +7,6 @@ class AtomicNumbers {
var AtomicNumbers = (function () {
function AtomicNumbers() {
}
AtomicNumbers.H = 1;
return AtomicNumbers;
}());
AtomicNumbers.H = 1;
@@ -14,7 +14,6 @@ obj[Symbol.foo];
var Symbol;
var obj = (_a = {},
_a[Symbol.foo] = 0,
_a
);
_a);
obj[Symbol.foo];
var _a;
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 27,
"tags": {
"0": {
"kind": "JSDocTypeTag",
"pos": 8,
"end": 22,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 14,
"end": 22,
"type": {
"kind": "NumberKeyword",
"pos": 15,
"end": 21
}
}
},
"length": 1,
"pos": 8,
"end": 22
}
}
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 27,
"tags": {
"0": {
"kind": "JSDocTypeTag",
"pos": 8,
"end": 22,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 14,
"end": 22,
"type": {
"kind": "NumberKeyword",
"pos": 15,
"end": 21
}
}
},
"length": 1,
"pos": 8,
"end": 22
}
}
@@ -0,0 +1,26 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 20,
"tags": {
"0": {
"kind": "JSDocReturnTag",
"pos": 8,
"end": 15,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"text": "return"
}
},
"length": 1,
"pos": 8,
"end": 15
}
}
@@ -0,0 +1,26 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 18,
"tags": {
"0": {
"kind": "JSDocTypeTag",
"pos": 8,
"end": 13,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
}
},
"length": 1,
"pos": 8,
"end": 13
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 34,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
}
},
"length": 1,
"pos": 8,
"end": 29
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 59,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
}
},
"length": 1,
"pos": 8,
"end": 29
}
}
@@ -0,0 +1,43 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 61,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 31,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 25,
"end": 30,
"text": "name1"
},
"isBracketed": true
},
"length": 1,
"pos": 8,
"end": 31
}
}
@@ -0,0 +1,43 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 66,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 36,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 26,
"end": 31,
"text": "name1"
},
"isBracketed": true
},
"length": 1,
"pos": 8,
"end": 36
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 34,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"preParameterName": {
"kind": "Identifier",
"pos": 15,
"end": 20,
"text": "name1"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 21,
"end": 29,
"type": {
"kind": "NumberKeyword",
"pos": 22,
"end": 28
}
}
},
"length": 1,
"pos": 8,
"end": 29
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 46,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"preParameterName": {
"kind": "Identifier",
"pos": 15,
"end": 20,
"text": "name1"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 21,
"end": 29,
"type": {
"kind": "NumberKeyword",
"pos": 22,
"end": 28
}
}
},
"length": 1,
"pos": 8,
"end": 29
}
}
@@ -0,0 +1,32 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 23,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 18,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"preParameterName": {
"kind": "Identifier",
"pos": 15,
"end": 18,
"text": "foo"
}
},
"length": 1,
"pos": 8,
"end": 18
}
}
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 29,
"tags": {
"0": {
"kind": "JSDocReturnTag",
"pos": 8,
"end": 24,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"text": "return"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 16,
"end": 24,
"type": {
"kind": "NumberKeyword",
"pos": 17,
"end": 23
}
}
},
"length": 1,
"pos": 8,
"end": 24
}
}
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 54,
"tags": {
"0": {
"kind": "JSDocReturnTag",
"pos": 8,
"end": 24,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"text": "return"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 16,
"end": 24,
"type": {
"kind": "NumberKeyword",
"pos": 17,
"end": 23
}
}
},
"length": 1,
"pos": 8,
"end": 24
}
}
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 30,
"tags": {
"0": {
"kind": "JSDocReturnTag",
"pos": 8,
"end": 25,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 16,
"text": "returns"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 17,
"end": 25,
"type": {
"kind": "NumberKeyword",
"pos": 18,
"end": 24
}
}
},
"length": 1,
"pos": 8,
"end": 25
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 24,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 19,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "T"
}
},
"length": 1,
"pos": 17,
"end": 19
}
},
"length": 1,
"pos": 8,
"end": 19
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 26,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 21,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "K"
}
},
"1": {
"kind": "TypeParameter",
"pos": 20,
"end": 21,
"name": {
"kind": "Identifier",
"pos": 20,
"end": 21,
"text": "V"
}
},
"length": 2,
"pos": 17,
"end": 21
}
},
"length": 1,
"pos": 8,
"end": 21
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 27,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 22,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "K"
}
},
"1": {
"kind": "TypeParameter",
"pos": 21,
"end": 22,
"name": {
"kind": "Identifier",
"pos": 21,
"end": 22,
"text": "V"
}
},
"length": 2,
"pos": 17,
"end": 22
}
},
"length": 1,
"pos": 8,
"end": 22
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 27,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 22,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "K"
}
},
"1": {
"kind": "TypeParameter",
"pos": 21,
"end": 22,
"name": {
"kind": "Identifier",
"pos": 21,
"end": 22,
"text": "V"
}
},
"length": 2,
"pos": 17,
"end": 22
}
},
"length": 1,
"pos": 8,
"end": 22
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 28,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 23,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "K"
}
},
"1": {
"kind": "TypeParameter",
"pos": 22,
"end": 23,
"name": {
"kind": "Identifier",
"pos": 22,
"end": 23,
"text": "V"
}
},
"length": 2,
"pos": 17,
"end": 23
}
},
"length": 1,
"pos": 8,
"end": 23
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 60,
"tags": {
"0": {
"kind": "JSDocTemplateTag",
"pos": 8,
"end": 23,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 17,
"text": "template"
},
"typeParameters": {
"0": {
"kind": "TypeParameter",
"pos": 18,
"end": 19,
"name": {
"kind": "Identifier",
"pos": 18,
"end": 19,
"text": "K"
}
},
"1": {
"kind": "TypeParameter",
"pos": 22,
"end": 23,
"name": {
"kind": "Identifier",
"pos": 22,
"end": 23,
"text": "V"
}
},
"length": 2,
"pos": 17,
"end": 23
}
},
"length": 1,
"pos": 8,
"end": 23
}
}
@@ -0,0 +1,74 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 60,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
}
},
"1": {
"kind": "JSDocParameterTag",
"pos": 34,
"end": 55,
"atToken": {
"kind": "AtToken",
"pos": 34,
"end": 35
},
"tagName": {
"kind": "Identifier",
"pos": 35,
"end": 40,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 41,
"end": 49,
"type": {
"kind": "NumberKeyword",
"pos": 42,
"end": 48
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 50,
"end": 55,
"text": "name2"
}
},
"length": 2,
"pos": 8,
"end": 55
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 56,
"tags": {
"0": {
"kind": "JSDocParameterTag",
"pos": 8,
"end": 29,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 14,
"text": "param"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 15,
"end": 23,
"type": {
"kind": "NumberKeyword",
"pos": 16,
"end": 22
}
},
"postParameterName": {
"kind": "Identifier",
"pos": 24,
"end": 29,
"text": "name1"
}
},
"length": 1,
"pos": 8,
"end": 29
}
}
@@ -0,0 +1,36 @@
{
"kind": "JSDocComment",
"pos": 0,
"end": 27,
"tags": {
"0": {
"kind": "JSDocTypeTag",
"pos": 8,
"end": 22,
"atToken": {
"kind": "AtToken",
"pos": 8,
"end": 9
},
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 13,
"text": "type"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 14,
"end": 22,
"type": {
"kind": "NumberKeyword",
"pos": 15,
"end": 21
}
}
},
"length": 1,
"pos": 8,
"end": 22
}
}
@@ -0,0 +1,5 @@
{
"kind": "JSDocAllType",
"pos": 1,
"end": 2
}
@@ -0,0 +1,16 @@
{
"kind": "JSDocArrayType",
"pos": 1,
"end": 4,
"elementType": {
"kind": "JSDocTypeReference",
"pos": 1,
"end": 2,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
}
}
}
@@ -0,0 +1,21 @@
{
"kind": "JSDocArrayType",
"pos": 1,
"end": 6,
"elementType": {
"kind": "JSDocArrayType",
"pos": 1,
"end": 4,
"elementType": {
"kind": "JSDocTypeReference",
"pos": 1,
"end": 2,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
}
}
}
}
@@ -0,0 +1,26 @@
{
"kind": "JSDocOptionalType",
"pos": 1,
"end": 7,
"type": {
"kind": "JSDocArrayType",
"pos": 1,
"end": 6,
"elementType": {
"kind": "JSDocArrayType",
"pos": 1,
"end": 4,
"elementType": {
"kind": "JSDocTypeReference",
"pos": 1,
"end": 2,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
}
}
}
}
}
@@ -0,0 +1,30 @@
{
"kind": "JSDocFunctionType",
"pos": 1,
"end": 26,
"parameters": {
"0": {
"kind": "Parameter",
"pos": 10,
"end": 16,
"type": {
"kind": "StringKeyword",
"pos": 10,
"end": 16
}
},
"1": {
"kind": "Parameter",
"pos": 17,
"end": 25,
"type": {
"kind": "BooleanKeyword",
"pos": 17,
"end": 25
}
},
"length": 2,
"pos": 10,
"end": 25
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocFunctionType",
"pos": 1,
"end": 11,
"parameters": {
"length": 0,
"pos": 10,
"end": 10
}
}
@@ -0,0 +1,30 @@
{
"kind": "JSDocFunctionType",
"pos": 1,
"end": 26,
"parameters": {
"0": {
"kind": "Parameter",
"pos": 10,
"end": 16,
"type": {
"kind": "StringKeyword",
"pos": 10,
"end": 16
}
},
"1": {
"kind": "Parameter",
"pos": 17,
"end": 25,
"type": {
"kind": "BooleanKeyword",
"pos": 17,
"end": 25
}
},
"length": 2,
"pos": 10,
"end": 25
}
}
@@ -0,0 +1,12 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 4,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 4,
"originalKeywordKind": "VarKeyword",
"text": "var"
}
}
@@ -0,0 +1,12 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 5,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 5,
"originalKeywordKind": "NullKeyword",
"text": "null"
}
}
@@ -0,0 +1,11 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 10,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 10,
"text": "undefined"
}
}
@@ -0,0 +1,27 @@
{
"kind": "JSDocConstructorType",
"pos": 1,
"end": 8,
"type": {
"kind": "JSDocTypeReference",
"pos": 5,
"end": 8,
"name": {
"kind": "FirstNode",
"pos": 5,
"end": 8,
"left": {
"kind": "Identifier",
"pos": 5,
"end": 6,
"text": "a"
},
"right": {
"kind": "Identifier",
"pos": 7,
"end": 8,
"text": "b"
}
}
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocNonNullableType",
"pos": 1,
"end": 8,
"type": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocNonNullableType",
"pos": 1,
"end": 8,
"type": {
"kind": "NumberKeyword",
"pos": 1,
"end": 7
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocNullableType",
"pos": 1,
"end": 8,
"type": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocNullableType",
"pos": 1,
"end": 8,
"type": {
"kind": "NumberKeyword",
"pos": 1,
"end": 7
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocOptionalType",
"pos": 1,
"end": 3,
"type": {
"kind": "JSDocUnknownType",
"pos": 1,
"end": 2
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocOptionalType",
"pos": 1,
"end": 8,
"type": {
"kind": "NumberKeyword",
"pos": 1,
"end": 7
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 3,
"members": {
"length": 0,
"pos": 2,
"end": 2
}
}
@@ -0,0 +1,21 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 6,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 5,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
}
},
"length": 1,
"pos": 2,
"end": 5
}
}
@@ -0,0 +1,26 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 14,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 13,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
},
"type": {
"kind": "NumberKeyword",
"pos": 6,
"end": 13
}
},
"length": 1,
"pos": 2,
"end": 13
}
}
@@ -0,0 +1,32 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 11,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 5,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
}
},
"1": {
"kind": "JSDocRecordMember",
"pos": 6,
"end": 10,
"name": {
"kind": "Identifier",
"pos": 6,
"end": 10,
"text": "bar"
}
},
"length": 2,
"pos": 2,
"end": 10
}
}
@@ -0,0 +1,37 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 19,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 13,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
},
"type": {
"kind": "NumberKeyword",
"pos": 6,
"end": 13
}
},
"1": {
"kind": "JSDocRecordMember",
"pos": 14,
"end": 18,
"name": {
"kind": "Identifier",
"pos": 14,
"end": 18,
"text": "bar"
}
},
"length": 2,
"pos": 2,
"end": 18
}
}
@@ -0,0 +1,37 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 19,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 5,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
}
},
"1": {
"kind": "JSDocRecordMember",
"pos": 6,
"end": 18,
"name": {
"kind": "Identifier",
"pos": 6,
"end": 10,
"text": "bar"
},
"type": {
"kind": "NumberKeyword",
"pos": 11,
"end": 18
}
},
"length": 2,
"pos": 2,
"end": 18
}
}
@@ -0,0 +1,42 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 27,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 13,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 5,
"text": "foo"
},
"type": {
"kind": "NumberKeyword",
"pos": 6,
"end": 13
}
},
"1": {
"kind": "JSDocRecordMember",
"pos": 14,
"end": 26,
"name": {
"kind": "Identifier",
"pos": 14,
"end": 18,
"text": "bar"
},
"type": {
"kind": "NumberKeyword",
"pos": 19,
"end": 26
}
},
"length": 2,
"pos": 2,
"end": 26
}
}
@@ -0,0 +1,22 @@
{
"kind": "JSDocRecordType",
"pos": 1,
"end": 11,
"members": {
"0": {
"kind": "JSDocRecordMember",
"pos": 2,
"end": 10,
"name": {
"kind": "Identifier",
"pos": 2,
"end": 10,
"originalKeywordKind": "FunctionKeyword",
"text": "function"
}
},
"length": 1,
"pos": 2,
"end": 10
}
}
@@ -0,0 +1,27 @@
{
"kind": "JSDocThisType",
"pos": 1,
"end": 9,
"type": {
"kind": "JSDocTypeReference",
"pos": 6,
"end": 9,
"name": {
"kind": "FirstNode",
"pos": 6,
"end": 9,
"left": {
"kind": "Identifier",
"pos": 6,
"end": 7,
"text": "a"
},
"right": {
"kind": "Identifier",
"pos": 8,
"end": 9,
"text": "b"
}
}
}
}
@@ -0,0 +1,20 @@
{
"kind": "JSDocUnionType",
"pos": 1,
"end": 14,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 1,
"end": 7
},
"1": {
"kind": "StringKeyword",
"pos": 8,
"end": 14
},
"length": 2,
"pos": 1,
"end": 14
}
}
@@ -0,0 +1,10 @@
{
"kind": "JSDocTupleType",
"pos": 1,
"end": 3,
"types": {
"length": 0,
"pos": 2,
"end": 2
}
}
@@ -0,0 +1,15 @@
{
"kind": "JSDocTupleType",
"pos": 1,
"end": 9,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
},
"length": 1,
"pos": 2,
"end": 8
}
}
@@ -0,0 +1,20 @@
{
"kind": "JSDocTupleType",
"pos": 1,
"end": 16,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
},
"1": {
"kind": "StringKeyword",
"pos": 9,
"end": 15
},
"length": 2,
"pos": 2,
"end": 15
}
}
@@ -0,0 +1,25 @@
{
"kind": "JSDocTupleType",
"pos": 1,
"end": 24,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
},
"1": {
"kind": "StringKeyword",
"pos": 9,
"end": 15
},
"2": {
"kind": "BooleanKeyword",
"pos": 16,
"end": 23
},
"length": 3,
"pos": 2,
"end": 23
}
}
@@ -0,0 +1,21 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 11,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
},
"typeArguments": {
"0": {
"kind": "NumberKeyword",
"pos": 4,
"end": 10
},
"length": 1,
"pos": 4,
"end": 10
}
}
@@ -0,0 +1,26 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 18,
"name": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
},
"typeArguments": {
"0": {
"kind": "NumberKeyword",
"pos": 4,
"end": 10
},
"1": {
"kind": "StringKeyword",
"pos": 11,
"end": 17
},
"length": 2,
"pos": 4,
"end": 17
}
}
@@ -0,0 +1,23 @@
{
"kind": "JSDocTypeReference",
"pos": 1,
"end": 11,
"name": {
"kind": "FirstNode",
"pos": 1,
"end": 11,
"left": {
"kind": "Identifier",
"pos": 1,
"end": 2,
"text": "a"
},
"right": {
"kind": "Identifier",
"pos": 3,
"end": 11,
"originalKeywordKind": "FunctionKeyword",
"text": "function"
}
}
}
@@ -0,0 +1,20 @@
{
"kind": "JSDocUnionType",
"pos": 1,
"end": 16,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 2,
"end": 8
},
"1": {
"kind": "StringKeyword",
"pos": 9,
"end": 15
},
"length": 2,
"pos": 2,
"end": 15
}
}
@@ -0,0 +1,5 @@
{
"kind": "JSDocUnknownType",
"pos": 1,
"end": 2
}

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