mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-16 05:58:32 -06:00
Fixed perf issue in binder, plus PR feedback
This commit is contained in:
parent
94018a13e6
commit
ad0dd4e2e2
@ -37,7 +37,7 @@ namespace ts {
|
||||
return ModuleInstanceState.ConstEnumOnly;
|
||||
}
|
||||
// 3. non-exported import declarations
|
||||
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(getModifierFlags(node) & ModifierFlags.Export)) {
|
||||
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && !(hasModifier(node, ModifierFlags.Export))) {
|
||||
return ModuleInstanceState.NonInstantiated;
|
||||
}
|
||||
// 4. other uninstantiated module declarations.
|
||||
@ -133,7 +133,7 @@ namespace ts {
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
// state used to aggregate transform flags during bind.
|
||||
let subtreeTransformFlags: TransformFlags;
|
||||
let subtreeTransformFlags: TransformFlags = TransformFlags.None;
|
||||
let skipTransformFlagAggregation: boolean;
|
||||
|
||||
function bindSourceFile(f: SourceFile, opts: CompilerOptions) {
|
||||
@ -141,7 +141,6 @@ namespace ts {
|
||||
options = opts;
|
||||
inStrictMode = !!file.externalModuleIndicator;
|
||||
classifiableNames = {};
|
||||
subtreeTransformFlags = undefined;
|
||||
skipTransformFlagAggregation = isDeclarationFile(file);
|
||||
|
||||
Symbol = objectAllocator.getSymbolConstructor();
|
||||
@ -167,6 +166,7 @@ namespace ts {
|
||||
hasAsyncFunctions = false;
|
||||
hasDecorators = false;
|
||||
hasParameterDecorators = false;
|
||||
subtreeTransformFlags = TransformFlags.None;
|
||||
}
|
||||
|
||||
return bindSourceFile;
|
||||
@ -256,7 +256,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return getModifierFlags(node) & ModifierFlags.Default ? "default" : undefined;
|
||||
return hasModifier(node, ModifierFlags.Default) ? "default" : undefined;
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return isJSDocConstructSignature(node) ? "__new" : "__call";
|
||||
case SyntaxKind.Parameter:
|
||||
@ -284,7 +284,7 @@ namespace ts {
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
||||
Debug.assert(!hasDynamicName(node));
|
||||
|
||||
const isDefaultExport = getModifierFlags(node) & ModifierFlags.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);
|
||||
|
||||
@ -329,7 +329,7 @@ namespace ts {
|
||||
: Diagnostics.Duplicate_identifier_0;
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
if (getModifierFlags(declaration) & ModifierFlags.Default) {
|
||||
if (hasModifier(declaration, ModifierFlags.Default)) {
|
||||
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
|
||||
}
|
||||
});
|
||||
@ -862,7 +862,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return getModifierFlags(node) & ModifierFlags.Static
|
||||
return hasModifier(node, ModifierFlags.Static)
|
||||
? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
|
||||
: declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
@ -899,7 +899,7 @@ namespace ts {
|
||||
function bindModuleDeclaration(node: ModuleDeclaration) {
|
||||
setExportContextFlag(node);
|
||||
if (isAmbientModule(node)) {
|
||||
if (getModifierFlags(node) & ModifierFlags.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);
|
||||
@ -1184,41 +1184,22 @@ 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.
|
||||
aggregateTransformFlagsIfNeededAndBindChildren(node);
|
||||
|
||||
inStrictMode = savedInStrictMode;
|
||||
}
|
||||
|
||||
function aggregateTransformFlagsIfNeededAndBindChildren(node: Node) {
|
||||
if (node.transformFlags !== undefined) {
|
||||
skipTransformFlagAggregationAndBindChildren(node);
|
||||
if (skipTransformFlagAggregation) {
|
||||
bindChildren(node);
|
||||
}
|
||||
else {
|
||||
aggregateTransformFlagsAndBindChildren(node);
|
||||
}
|
||||
}
|
||||
|
||||
function skipTransformFlagAggregationAndBindChildren(node: Node) {
|
||||
if (!skipTransformFlagAggregation) {
|
||||
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
|
||||
skipTransformFlagAggregation = true;
|
||||
bindChildren(node);
|
||||
skipTransformFlagAggregation = false;
|
||||
}
|
||||
else {
|
||||
bindChildren(node);
|
||||
}
|
||||
}
|
||||
|
||||
function aggregateTransformFlagsAndBindChildren(node: Node) {
|
||||
if (!skipTransformFlagAggregation) {
|
||||
const savedSubtreeTransformFlags = subtreeTransformFlags;
|
||||
subtreeTransformFlags = 0;
|
||||
bindChildren(node);
|
||||
subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
|
||||
}
|
||||
else {
|
||||
bindChildren(node);
|
||||
}
|
||||
|
||||
inStrictMode = savedInStrictMode;
|
||||
}
|
||||
|
||||
function updateStrictMode(node: Node) {
|
||||
@ -1799,15 +1780,9 @@ namespace ts {
|
||||
* @param subtreeFlags Transform flags computed for this node's subtree
|
||||
*/
|
||||
export function computeTransformFlagsForNode(node: Node, subtreeFlags: TransformFlags): TransformFlags {
|
||||
// Ambient nodes are TypeScript syntax and the flags of their subtree are ignored.
|
||||
if (getModifierFlags(node) & ModifierFlags.Ambient) {
|
||||
return (node.transformFlags = TransformFlags.AssertTypeScript)
|
||||
& ~(node.excludeTransformFlags = TransformFlags.NodeExcludes);
|
||||
}
|
||||
|
||||
// Mark transformations needed for each node
|
||||
let transformFlags: TransformFlags;
|
||||
let excludeFlags: TransformFlags;
|
||||
let transformFlags = TransformFlags.None;
|
||||
let excludeFlags = TransformFlags.None;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
@ -1823,7 +1798,7 @@ namespace ts {
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
// These nodes are TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxElement:
|
||||
@ -1835,12 +1810,12 @@ namespace ts {
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxExpression:
|
||||
// These nodes are Jsx syntax.
|
||||
transformFlags |= TransformFlags.AssertJsx;
|
||||
transformFlags = TransformFlags.AssertJsx;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportKeyword:
|
||||
// This node is both ES6 and TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.TypeScript;
|
||||
transformFlags = TransformFlags.AssertES6 | TransformFlags.TypeScript;
|
||||
break;
|
||||
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
@ -1854,10 +1829,9 @@ namespace ts {
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.YieldExpression:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
break;
|
||||
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@ -1886,36 +1860,42 @@ namespace ts {
|
||||
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;
|
||||
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;
|
||||
transformFlags = TransformFlags.ContainsComputedPropertyName;
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
// This node is ES6 syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadElementExpression;
|
||||
transformFlags = TransformFlags.ContainsSpreadElementExpression;
|
||||
break;
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// Mark this node and its ancestors as containing a lexical `this` keyword.
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
transformFlags = TransformFlags.ContainsLexicalThis;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
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:
|
||||
@ -1923,20 +1903,12 @@ namespace ts {
|
||||
if (subtreeFlags & TransformFlags.ContainsComputedPropertyName) {
|
||||
// If an ObjectLiteralExpression contains a ComputedPropertyName, then it
|
||||
// is an ES6 node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
return computeCallExpression(<CallExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
@ -1944,179 +1916,66 @@ namespace ts {
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
|
||||
// If the this node contains a SpreadElementExpression, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
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.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;
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
// If the node is synthesized, it means the emitter put the parentheses there,
|
||||
// not the user. If we didn't want them, the emitter would not have put them
|
||||
// there.
|
||||
if (!nodeIsSynthesized(node)) {
|
||||
if ((<ParenthesizedExpression>node).expression.kind === SyntaxKind.AsExpression
|
||||
|| (<ParenthesizedExpression>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 ((<ParenthesizedExpression>node).expression.transformFlags & TransformFlags.DestructuringAssignment) {
|
||||
transformFlags |= TransformFlags.DestructuringAssignment;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeParenthesizedExpression(<ParenthesizedExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (isDestructuringAssignment(node)) {
|
||||
// Destructuring assignments are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.DestructuringAssignment;
|
||||
}
|
||||
else if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AsteriskAsteriskToken
|
||||
|| (<BinaryExpression>node).operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
// Exponentiation is ES7 syntax.
|
||||
transformFlags |= TransformFlags.AssertES7;
|
||||
}
|
||||
|
||||
break;
|
||||
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;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// If the parameter has a question token, then it is TypeScript syntax.
|
||||
if ((<ParameterDeclaration>node).questionToken) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// If a parameter has an accessibility modifier, then it is TypeScript syntax.
|
||||
if (getModifierFlags(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 ((<ParameterDeclaration>node).initializer
|
||||
|| (<ParameterDeclaration>node).dotDotDotToken
|
||||
|| isBindingPattern((<ParameterDeclaration>node).name)) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeParameter(<ParameterDeclaration>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
|
||||
excludeFlags = TransformFlags.ArrowFunctionExcludes;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
|
||||
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
|
||||
}
|
||||
|
||||
// An async arrow function is TypeScript syntax.
|
||||
if (getModifierFlags(node) & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeArrowFunction(<ArrowFunction>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// A FunctionExpression excludes markers that should not escape the scope of a FunctionExpression.
|
||||
excludeFlags = TransformFlags.FunctionExcludes;
|
||||
|
||||
// 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 ((<FunctionLikeDeclaration>node).asteriskToken
|
||||
|| subtreeFlags & TransformFlags.ContainsCapturedLexicalThis
|
||||
|| subtreeFlags & TransformFlags.ContainsDefaultValueAssignments) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
// An async function expression is TypeScript syntax.
|
||||
if (getModifierFlags(node) & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeFunctionExpression(<FunctionExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// A FunctionDeclaration excludes markers that should not escape the scope of a FunctionDeclaration.
|
||||
excludeFlags = TransformFlags.FunctionExcludes;
|
||||
|
||||
// A FunctionDeclaration without a body is an overload and is TypeScript syntax.
|
||||
if (!(<FunctionDeclaration>node).body) {
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
break;
|
||||
}
|
||||
|
||||
// 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 ((<FunctionDeclaration>node).asteriskToken
|
||||
|| getModifierFlags(node) & ModifierFlags.Export
|
||||
|| subtreeFlags & TransformFlags.ContainsCapturedLexicalThis
|
||||
|| subtreeFlags & TransformFlags.ContainsDefaultValueAssignments) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
// An async function declaration is TypeScript syntax.
|
||||
if (getModifierFlags(node) & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeFunctionDeclaration(<FunctionDeclaration>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
// A VariableDeclaration with a binding pattern is ES6 syntax.
|
||||
if (isBindingPattern((<VariableDeclaration>node).name)) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
break;
|
||||
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;
|
||||
transformFlags = TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
|
||||
if (getModifierFlags(node) & ModifierFlags.Export) {
|
||||
transformFlags |= TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeVariableStatement(<VariableStatement>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.LabeledStatement:
|
||||
// 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;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeLabeledStatement(<LabeledStatement>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
@ -2124,36 +1983,26 @@ namespace ts {
|
||||
case SyntaxKind.ForInStatement:
|
||||
// A loop containing a block scoped binding *may* need to be transformed from ES6.
|
||||
if (subtreeFlags & TransformFlags.ContainsBlockScopedBinding) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return computeClassDeclaration(<ClassDeclaration>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.ClassExpression:
|
||||
// A ClassDeclarations or ClassExpression is ES6 syntax.
|
||||
excludeFlags = TransformFlags.ClassExcludes;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsParameterPropertyAssignments
|
||||
|| subtreeFlags & TransformFlags.ContainsPropertyInitializer
|
||||
|| subtreeFlags & TransformFlags.ContainsDecorators) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
return computeClassExpression(<ClassExpression>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.HeritageClause:
|
||||
if ((<HeritageClause>node).token === SyntaxKind.ExtendsKeyword) {
|
||||
// An `extends` HeritageClause is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
}
|
||||
else {
|
||||
// An `implements` HeritageClause is TypeScript syntax.
|
||||
Debug.assert((<HeritageClause>node).token === SyntaxKind.ImplementsKeyword);
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2161,7 +2010,7 @@ namespace ts {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
// An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
|
||||
// extends clause of a class.
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
|
||||
// If an ExpressionWithTypeArguments contains type arguments, then it
|
||||
// is TypeScript syntax.
|
||||
@ -2174,7 +2023,7 @@ namespace ts {
|
||||
case SyntaxKind.Constructor:
|
||||
// A Constructor is ES6 syntax.
|
||||
excludeFlags = TransformFlags.ConstructorExcludes;
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
|
||||
// An overload constructor is TypeScript syntax.
|
||||
if (!(<ConstructorDeclaration>node).body) {
|
||||
@ -2185,7 +2034,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// A PropertyDeclaration is TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
|
||||
// If the PropertyDeclaration has an initializer, we need to inform its ancestor
|
||||
// so that it handle the transformation.
|
||||
@ -2198,13 +2047,13 @@ namespace ts {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// A MethodDeclaration is ES6 syntax.
|
||||
excludeFlags = TransformFlags.MethodOrAccessorExcludes;
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
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
|
||||
|| getModifierFlags(node) & (ModifierFlags.Async | ModifierFlags.Abstract)
|
||||
|| hasModifier(node, ModifierFlags.Async | ModifierFlags.Abstract)
|
||||
|| (subtreeFlags & TransformFlags.ContainsDecorators
|
||||
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
@ -2219,10 +2068,10 @@ namespace ts {
|
||||
|
||||
// A GetAccessor or SetAccessor is TypeScript syntax if it is either abstract,
|
||||
// or has both a computed property name and a decorator.
|
||||
if (getModifierFlags(node) & ModifierFlags.Abstract ||
|
||||
subtreeFlags & TransformFlags.ContainsDecorators &&
|
||||
subtreeFlags & TransformFlags.ContainsComputedPropertyName) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
if (hasModifier(node, ModifierFlags.Abstract)
|
||||
|| (subtreeFlags & TransformFlags.ContainsDecorators
|
||||
&& subtreeFlags & TransformFlags.ContainsComputedPropertyName)) {
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2230,7 +2079,7 @@ namespace ts {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
// An ImportEqualsDeclaration with a namespace reference is TypeScript.
|
||||
if (!isExternalModuleImportEqualsDeclaration(node)) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -2239,20 +2088,258 @@ namespace ts {
|
||||
// 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;
|
||||
transformFlags = TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
if (subtreeFlags & TransformFlags.ContainsCapturedLexicalThis) {
|
||||
transformFlags |= TransformFlags.AssertES6;
|
||||
transformFlags = TransformFlags.AssertES6;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return (node.transformFlags = subtreeFlags | transformFlags)
|
||||
& ~(node.excludeTransformFlags = excludeFlags | TransformFlags.NodeExcludes);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1013,8 +1013,9 @@ namespace ts {
|
||||
this.pos = pos;
|
||||
this.end = end;
|
||||
this.flags = NodeFlags.None;
|
||||
this.transformFlags = undefined;
|
||||
this.excludeTransformFlags = undefined;
|
||||
this.modifierFlagsCache = ModifierFlags.None;
|
||||
this.transformFlags = TransformFlags.None;
|
||||
this.excludeTransformFlags = TransformFlags.None;
|
||||
this.parent = undefined;
|
||||
this.original = undefined;
|
||||
}
|
||||
|
||||
@ -168,6 +168,26 @@ namespace ts {
|
||||
]);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@ -209,186 +229,186 @@ namespace ts {
|
||||
* @param node The ImportDeclaration node.
|
||||
*/
|
||||
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
const statements: Statement[] = [];
|
||||
const namespaceDeclaration = getNamespaceDeclarationNode(node);
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
if (!node.importClause) {
|
||||
// import "mod";
|
||||
addNode(statements,
|
||||
createStatement(
|
||||
createRequireCall(node),
|
||||
/*location*/ node
|
||||
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 {
|
||||
const variables: VariableDeclaration[] = [];
|
||||
if (namespaceDeclaration && !isDefaultImport(node)) {
|
||||
// import * as n from "mod";
|
||||
// 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),
|
||||
createRequireCall(node)
|
||||
getGeneratedNameForNode(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),
|
||||
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 if (namespaceDeclaration && isDefaultImport(node)) {
|
||||
// import d, * as n from "mod";
|
||||
else {
|
||||
addNode(statements,
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
getSynthesizedClone(namespaceDeclaration.name),
|
||||
getGeneratedNameForNode(node),
|
||||
getSynthesizedClone(node.name),
|
||||
createRequireCall(node),
|
||||
/*location*/ node
|
||||
)
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
addExportImportAssignments(statements, node);
|
||||
return statements;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
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;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
if (contains(externalImports, node)) {
|
||||
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
|
||||
else {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
addNode(statements,
|
||||
createStatement(
|
||||
createExportAssignment(node.name, node.name),
|
||||
/*location*/ node
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
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> {
|
||||
@ -605,26 +625,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function getModuleMemberName(name: Identifier) {
|
||||
return createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
@ -669,9 +669,10 @@ namespace ts {
|
||||
|
||||
function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
|
||||
const moduleName = getExternalModuleNameLiteral(importNode);
|
||||
Debug.assert(isDefined(moduleName));
|
||||
return createCall(
|
||||
createIdentifier("require"),
|
||||
moduleName ? [moduleName] : []
|
||||
[moduleName]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -419,7 +419,9 @@ namespace ts {
|
||||
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
|
||||
Const = 1 << 11, // Variable declaration
|
||||
|
||||
HasComputedFlags = 1 << 31, // Modifier flags have been computed
|
||||
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
NonPublicAccessibilityModifier = Private | Protected,
|
||||
@ -450,10 +452,11 @@ 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?: NodeArray<Modifier>; // 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)
|
||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||
@ -2761,6 +2764,8 @@ namespace ts {
|
||||
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,
|
||||
@ -2771,7 +2776,7 @@ namespace ts {
|
||||
// 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,
|
||||
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,
|
||||
|
||||
@ -190,7 +190,7 @@ namespace ts {
|
||||
// However, this node will be 'missing' in the sense that no actual source-code/tokens are
|
||||
// contained within it.
|
||||
export function nodeIsMissing(node: Node) {
|
||||
if (!node) {
|
||||
if (node === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2561,19 +2561,26 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function hasModifier(node: Node, flags: ModifierFlags) {
|
||||
return (getModifierFlags(node) & flags) != 0;
|
||||
return (getModifierFlags(node) & flags) !== 0;
|
||||
}
|
||||
|
||||
export function getModifierFlags(node: Node): ModifierFlags {
|
||||
if (node.modifierFlagsCache & ModifierFlags.HasComputedFlags) {
|
||||
return node.modifierFlagsCache & ~ModifierFlags.HasComputedFlags;
|
||||
}
|
||||
|
||||
let flags = ModifierFlags.None;
|
||||
if (node.modifiers) {
|
||||
for (const modifier of node.modifiers) {
|
||||
flags |= modifierToFlag(modifier.kind);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.flags & NodeFlags.NestedNamespace) {
|
||||
flags |= ModifierFlags.Export;
|
||||
}
|
||||
|
||||
node.modifierFlagsCache = flags | ModifierFlags.HasComputedFlags;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
@ -882,15 +882,15 @@ namespace ts {
|
||||
*/
|
||||
function aggregateTransformFlagsForNode(node: Node): TransformFlags {
|
||||
if (node === undefined) {
|
||||
return <TransformFlags>0;
|
||||
return TransformFlags.None;
|
||||
}
|
||||
|
||||
if (node.transformFlags === undefined) {
|
||||
else if (node.transformFlags & TransformFlags.HasComputedFlags) {
|
||||
return node.transformFlags & ~node.excludeTransformFlags;
|
||||
}
|
||||
else {
|
||||
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
|
||||
return computeTransformFlagsForNode(node, subtreeFlags);
|
||||
}
|
||||
|
||||
return node.transformFlags & ~node.excludeTransformFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user