Added support for System modules.

This commit is contained in:
Ron Buckton 2015-10-23 17:14:51 -07:00
parent aa639d3ce7
commit 686c94cd67
20 changed files with 5231 additions and 2336 deletions

View File

@ -44,8 +44,12 @@ var compilerSources = [
"binder.ts",
"checker.ts",
"transform.ts",
"transforms/jsx.ts",
"transforms/destructuring.ts",
"transforms/ts.ts",
"transforms/module/module.ts",
"transforms/module/system.ts",
"transforms/module/es6.ts",
"transforms/jsx.ts",
"transforms/es6.ts",
"declarationEmitter.ts",
"printer.ts",
@ -70,8 +74,12 @@ var servicesSources = [
"binder.ts",
"checker.ts",
"transform.ts",
"transforms/jsx.ts",
"transforms/destructuring.ts",
"transforms/ts.ts",
"transforms/module/module.ts",
"transforms/module/system.ts",
"transforms/module/es6.ts",
"transforms/jsx.ts",
"transforms/es6.ts",
"declarationEmitter.ts",
"printer.ts",
@ -954,7 +962,7 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
desc("Compiles tslint rules to js");
task("build-rules", tslintRulesOutFiles);
tslintRulesFiles.forEach(function(ruleFile, i) {
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
});
function getLinterOptions() {
@ -1014,7 +1022,7 @@ function lintWatchFile(filename) {
if (event !== "change") {
return;
}
if (!lintSemaphores[filename]) {
lintSemaphores[filename] = true;
lintFileAsync(getLinterOptions(), filename, function(err, result) {

View File

@ -73,11 +73,17 @@ namespace ts {${each(discovery.createableNodes, syntaxNode => `
export function cloneNode<TNode extends Node>(node: TNode, location?: TextRange, flags?: NodeFlags): TNode;
export function cloneNode(node: Node, location?: TextRange, flags: NodeFlags = node.flags): Node {
if (node) {
let clone: Node;
switch (node.kind) {${each(discovery.createableNodes, syntaxNode => `
case SyntaxKind.${syntaxNode.kindName}:
return ${syntaxNode.createFunctionName}(${each(syntaxNode.createParameters, member =>
clone = ${syntaxNode.createFunctionName}(${each(syntaxNode.createParameters, member =>
`(<${syntaxNode.typeName}>node).${member.propertyName}, `
)}location, flags);`)}
)}location, flags);
break;`)}
}
if (clone) {
clone.original = node;
return clone;
}
}
return node;

View File

@ -1242,8 +1242,11 @@ namespace ts {
// & ~(node.excludeTransformFlags = TransformFlags.CallOrArrayLiteralExcludes);
case SyntaxKind.ExpressionStatement:
if (node.flags & NodeFlags.GeneratedSuper) {
transformFlags |= TransformFlags.ThisNodeIsES6;
if (node.flags & NodeFlags.Generated) {
let expression = (<ExpressionStatement>node).expression;
if (isCallExpression(expression) && isSuperKeyword(expression.expression)) {
transformFlags |= TransformFlags.ThisNodeIsES6;
}
}
break;
@ -1465,7 +1468,7 @@ namespace ts {
// break;
case SyntaxKind.ImportEqualsDeclaration:
// An ImportEqualsDeclaration with a namespace reference is TypeScript.
// An ImportEqualsDeclaration is TypeScriptwith a namespace reference is TypeScript.
if (!isExternalModuleImportEqualsDeclaration(node)) {
transformFlags |= TransformFlags.ThisNodeIsTypeScript;
}

View File

@ -169,7 +169,6 @@ namespace ts {
let emitParam = false;
let emitAwaiter = false;
let emitGenerator = false;
let emitExportStar = false;
let resolutionTargets: TypeSystemEntity[] = [];
let resolutionResults: boolean[] = [];
@ -13701,8 +13700,6 @@ namespace ts {
if (moduleSymbol && moduleSymbol.exports["export="]) {
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
}
emitExportStar = true;
}
}
}
@ -14055,7 +14052,6 @@ namespace ts {
emitParam = false;
emitAwaiter = false;
emitGenerator = false;
emitExportStar = false;
potentialThisCollisions.length = 0;
forEach(node.statements, checkSourceElement);
@ -14090,10 +14086,6 @@ namespace ts {
links.flags |= NodeCheckFlags.EmitGenerator;
}
if (emitExportStar) {
links.flags |= NodeCheckFlags.EmitExportStar;
}
links.flags |= NodeCheckFlags.TypeChecked;
}
}

View File

@ -832,7 +832,7 @@ namespace ts {
/**
* List of extensions that will be used to look for external modules.
* This list is kept separate from supportedExtensions to for cases when we'll allow to include .js files in compilation,
* but still would like to load only TypeScript files as modules
* but still would like to load only TypeScript files as modules
*/
export const moduleFileExtensions = supportedExtensions;
@ -1163,6 +1163,7 @@ namespace ts {
verboseDebugString = "\r\nVerbose Debug Information: " + verboseDebugInfo();
}
debugger;
throw new Error("Debug Failure. False expression: " + (message || "") + verboseDebugString);
}
}

View File

@ -1,7 +1,7 @@
/// <reference path="checker.ts"/>
/// <reference path="transform.ts" />
/// <reference path="declarationEmitter.ts"/>
/// <reference path="printer.ts" />
/// <reference path="transform.ts"/>
/// <reference path="printer.ts"/>
/* @internal */
namespace ts {
@ -328,13 +328,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let newLine = host.getNewLine();
let jsxDesugaring = host.getCompilerOptions().jsx !== JsxEmit.Preserve;
let shouldEmitJsx = (s: SourceFile) => (s.languageVariant === LanguageVariant.JSX && !jsxDesugaring);
let transformationChain = getTransformationChain(compilerOptions);
let sourceFiles: SourceFile[];
let substitutions: TransformationSubstitutions;
if (targetSourceFile === undefined) {
({ sourceFiles, substitutions } = transformFilesIfNeeded(resolver, host, host.getSourceFiles(), transformationChain));
forEach(sourceFiles, sourceFile => {
forEach(host.getSourceFiles(), sourceFile => {
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
let jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, sourceFile);
@ -349,11 +345,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
// targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
let jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, shouldEmitJsx(targetSourceFile) ? ".jsx" : ".js");
({ sourceFiles: [targetSourceFile], substitutions } = transformFilesIfNeeded(resolver, host, [targetSourceFile], transformationChain));
emitFile(jsFilePath, targetSourceFile);
}
else if (!isDeclarationFile(targetSourceFile) && (compilerOptions.outFile || compilerOptions.out)) {
({ sourceFiles, substitutions } = transformFilesIfNeeded(resolver, host, host.getSourceFiles(), transformationChain));
emitFile(compilerOptions.outFile || compilerOptions.out);
}
}
@ -7044,7 +7038,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
function emitDirectivePrologues(statements: Statement[], startWithNewLine: boolean): number {
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean): number {
for (let i = 0; i < statements.length; ++i) {
if (isPrologueDirective(statements[i])) {
if (startWithNewLine || i > 0) {
@ -7609,8 +7603,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function emitFile(jsFilePath: string, sourceFile?: SourceFile) {
if (compilerOptions.experimentalTransforms) {
let nodes = sourceFile ? [sourceFile] : sourceFiles;
let text = printNodes(resolver, substitutions, host, filter(nodes, isNonDeclarationFile));
let nodes = sourceFile ? [sourceFile] : host.getSourceFiles();
let text = printFiles(resolver, host, filter(nodes, isNonDeclarationFile), getTransformationChain(compilerOptions));
writeFile(host, diagnostics, jsFilePath, text, compilerOptions.emitBOM);
}
else {
@ -7618,7 +7612,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
if (compilerOptions.declaration) {
writeDeclarationFile(jsFilePath, getOriginalNodeIf(sourceFile, isSourceFile), host, resolver, diagnostics);
writeDeclarationFile(jsFilePath, sourceFile, host, resolver, diagnostics);
}
}
}

View File

@ -788,11 +788,9 @@ namespace ts {
if (initializer) node.initializer = initializer;
return node;
}
export function createShorthandPropertyAssignment(name?: Identifier, equalsToken?: Node, objectAssignmentInitializer?: Expression, location?: TextRange, flags?: NodeFlags): ShorthandPropertyAssignment {
export function createShorthandPropertyAssignment(name?: Identifier, location?: TextRange, flags?: NodeFlags): ShorthandPropertyAssignment {
let node = createNode<ShorthandPropertyAssignment>(SyntaxKind.ShorthandPropertyAssignment, location, flags);
if (name) node.name = name;
if (equalsToken) node.equalsToken = equalsToken;
if (objectAssignmentInitializer) node.objectAssignmentInitializer = objectAssignmentInitializer;
return node;
}
export function createEnumMember(name?: DeclarationName, initializer?: Expression, location?: TextRange, flags?: NodeFlags): EnumMember {
@ -1699,9 +1697,9 @@ namespace ts {
}
return node;
}
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, equalsToken: Node, objectAssignmentInitializer: Expression): ShorthandPropertyAssignment {
if (name !== node.name || equalsToken !== node.equalsToken || objectAssignmentInitializer !== node.objectAssignmentInitializer) {
let newNode = createShorthandPropertyAssignment(name, equalsToken, objectAssignmentInitializer);
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier): ShorthandPropertyAssignment {
if (name !== node.name) {
let newNode = createShorthandPropertyAssignment(name);
return updateFrom(node, newNode);
}
return node;
@ -2854,309 +2852,465 @@ namespace ts {
export function cloneNode<TNode extends Node>(node: TNode, location?: TextRange, flags?: NodeFlags): TNode;
export function cloneNode(node: Node, location?: TextRange, flags: NodeFlags = node.flags): Node {
if (node) {
let clone: Node;
switch (node.kind) {
case SyntaxKind.NumericLiteral:
return createNumericLiteral((<LiteralExpression>node).text, location, flags);
clone = createNumericLiteral((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.StringLiteral:
return createStringLiteral((<StringLiteral>node).text, location, flags);
clone = createStringLiteral((<StringLiteral>node).text, location, flags);
break;
case SyntaxKind.RegularExpressionLiteral:
return createRegularExpressionLiteral((<LiteralExpression>node).text, location, flags);
clone = createRegularExpressionLiteral((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.NoSubstitutionTemplateLiteral:
return createNoSubstitutionTemplateLiteral((<LiteralExpression>node).text, location, flags);
clone = createNoSubstitutionTemplateLiteral((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.TemplateHead:
return createTemplateHead((<LiteralExpression>node).text, location, flags);
clone = createTemplateHead((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.TemplateMiddle:
return createTemplateMiddle((<LiteralExpression>node).text, location, flags);
clone = createTemplateMiddle((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.TemplateTail:
return createTemplateTail((<LiteralExpression>node).text, location, flags);
clone = createTemplateTail((<LiteralExpression>node).text, location, flags);
break;
case SyntaxKind.Identifier:
return createIdentifier((<Identifier>node).text, (<Identifier>node).originalKeywordKind, location, flags);
clone = createIdentifier((<Identifier>node).text, (<Identifier>node).originalKeywordKind, location, flags);
break;
case SyntaxKind.FalseKeyword:
return createFalseKeyword(location, flags);
clone = createFalseKeyword(location, flags);
break;
case SyntaxKind.NullKeyword:
return createNullKeyword(location, flags);
clone = createNullKeyword(location, flags);
break;
case SyntaxKind.SuperKeyword:
return createSuperKeyword(location, flags);
clone = createSuperKeyword(location, flags);
break;
case SyntaxKind.ThisKeyword:
return createThisKeyword(location, flags);
clone = createThisKeyword(location, flags);
break;
case SyntaxKind.TrueKeyword:
return createTrueKeyword(location, flags);
clone = createTrueKeyword(location, flags);
break;
case SyntaxKind.QualifiedName:
return createQualifiedName((<QualifiedName>node).left, (<QualifiedName>node).right, location, flags);
clone = createQualifiedName((<QualifiedName>node).left, (<QualifiedName>node).right, location, flags);
break;
case SyntaxKind.ComputedPropertyName:
return createComputedPropertyName((<ComputedPropertyName>node).expression, location, flags);
clone = createComputedPropertyName((<ComputedPropertyName>node).expression, location, flags);
break;
case SyntaxKind.TypeParameter:
return createTypeParameter((<TypeParameterDeclaration>node).name, (<TypeParameterDeclaration>node).constraint, (<TypeParameterDeclaration>node).expression, location, flags);
clone = createTypeParameter((<TypeParameterDeclaration>node).name, (<TypeParameterDeclaration>node).constraint, (<TypeParameterDeclaration>node).expression, location, flags);
break;
case SyntaxKind.Parameter:
return createParameter((<ParameterDeclaration>node).decorators, (<ParameterDeclaration>node).modifiers, (<ParameterDeclaration>node).dotDotDotToken, (<ParameterDeclaration>node).name, (<ParameterDeclaration>node).questionToken, (<ParameterDeclaration>node).type, (<ParameterDeclaration>node).initializer, location, flags);
clone = createParameter((<ParameterDeclaration>node).decorators, (<ParameterDeclaration>node).modifiers, (<ParameterDeclaration>node).dotDotDotToken, (<ParameterDeclaration>node).name, (<ParameterDeclaration>node).questionToken, (<ParameterDeclaration>node).type, (<ParameterDeclaration>node).initializer, location, flags);
break;
case SyntaxKind.Decorator:
return createDecorator((<Decorator>node).expression, location, flags);
clone = createDecorator((<Decorator>node).expression, location, flags);
break;
case SyntaxKind.PropertySignature:
return createPropertySignature((<PropertySignature>node).decorators, (<PropertySignature>node).modifiers, (<PropertySignature>node).name, (<PropertySignature>node).questionToken, (<PropertySignature>node).type, location, flags);
clone = createPropertySignature((<PropertySignature>node).decorators, (<PropertySignature>node).modifiers, (<PropertySignature>node).name, (<PropertySignature>node).questionToken, (<PropertySignature>node).type, location, flags);
break;
case SyntaxKind.PropertyDeclaration:
return createPropertyDeclaration((<PropertyDeclaration>node).decorators, (<PropertyDeclaration>node).modifiers, (<PropertyDeclaration>node).name, (<PropertyDeclaration>node).type, (<PropertyDeclaration>node).initializer, location, flags);
clone = createPropertyDeclaration((<PropertyDeclaration>node).decorators, (<PropertyDeclaration>node).modifiers, (<PropertyDeclaration>node).name, (<PropertyDeclaration>node).type, (<PropertyDeclaration>node).initializer, location, flags);
break;
case SyntaxKind.MethodSignature:
return createMethodSignature((<MethodSignature>node).decorators, (<MethodSignature>node).modifiers, (<MethodSignature>node).name, (<MethodSignature>node).questionToken, (<MethodSignature>node).typeParameters, (<MethodSignature>node).parameters, (<MethodSignature>node).type, location, flags);
clone = createMethodSignature((<MethodSignature>node).decorators, (<MethodSignature>node).modifiers, (<MethodSignature>node).name, (<MethodSignature>node).questionToken, (<MethodSignature>node).typeParameters, (<MethodSignature>node).parameters, (<MethodSignature>node).type, location, flags);
break;
case SyntaxKind.MethodDeclaration:
return createMethodDeclaration((<MethodDeclaration>node).decorators, (<MethodDeclaration>node).modifiers, (<MethodDeclaration>node).asteriskToken, (<MethodDeclaration>node).name, (<MethodDeclaration>node).typeParameters, (<MethodDeclaration>node).parameters, (<MethodDeclaration>node).type, (<MethodDeclaration>node).body, location, flags);
clone = createMethodDeclaration((<MethodDeclaration>node).decorators, (<MethodDeclaration>node).modifiers, (<MethodDeclaration>node).asteriskToken, (<MethodDeclaration>node).name, (<MethodDeclaration>node).typeParameters, (<MethodDeclaration>node).parameters, (<MethodDeclaration>node).type, (<MethodDeclaration>node).body, location, flags);
break;
case SyntaxKind.Constructor:
return createConstructor((<ConstructorDeclaration>node).decorators, (<ConstructorDeclaration>node).modifiers, (<ConstructorDeclaration>node).parameters, (<ConstructorDeclaration>node).type, (<ConstructorDeclaration>node).body, location, flags);
clone = createConstructor((<ConstructorDeclaration>node).decorators, (<ConstructorDeclaration>node).modifiers, (<ConstructorDeclaration>node).parameters, (<ConstructorDeclaration>node).type, (<ConstructorDeclaration>node).body, location, flags);
break;
case SyntaxKind.GetAccessor:
return createGetAccessor((<GetAccessorDeclaration>node).decorators, (<GetAccessorDeclaration>node).modifiers, (<GetAccessorDeclaration>node).name, (<GetAccessorDeclaration>node).parameters, (<GetAccessorDeclaration>node).type, (<GetAccessorDeclaration>node).body, location, flags);
clone = createGetAccessor((<GetAccessorDeclaration>node).decorators, (<GetAccessorDeclaration>node).modifiers, (<GetAccessorDeclaration>node).name, (<GetAccessorDeclaration>node).parameters, (<GetAccessorDeclaration>node).type, (<GetAccessorDeclaration>node).body, location, flags);
break;
case SyntaxKind.SetAccessor:
return createSetAccessor((<SetAccessorDeclaration>node).decorators, (<SetAccessorDeclaration>node).modifiers, (<SetAccessorDeclaration>node).name, (<SetAccessorDeclaration>node).parameters, (<SetAccessorDeclaration>node).type, (<SetAccessorDeclaration>node).body, location, flags);
clone = createSetAccessor((<SetAccessorDeclaration>node).decorators, (<SetAccessorDeclaration>node).modifiers, (<SetAccessorDeclaration>node).name, (<SetAccessorDeclaration>node).parameters, (<SetAccessorDeclaration>node).type, (<SetAccessorDeclaration>node).body, location, flags);
break;
case SyntaxKind.CallSignature:
return createCallSignature((<CallSignatureDeclaration>node).typeParameters, (<CallSignatureDeclaration>node).parameters, (<CallSignatureDeclaration>node).type, (<CallSignatureDeclaration>node).questionToken, location, flags);
clone = createCallSignature((<CallSignatureDeclaration>node).typeParameters, (<CallSignatureDeclaration>node).parameters, (<CallSignatureDeclaration>node).type, (<CallSignatureDeclaration>node).questionToken, location, flags);
break;
case SyntaxKind.ConstructSignature:
return createConstructSignature((<ConstructSignatureDeclaration>node).typeParameters, (<ConstructSignatureDeclaration>node).parameters, (<ConstructSignatureDeclaration>node).type, (<ConstructSignatureDeclaration>node).questionToken, location, flags);
clone = createConstructSignature((<ConstructSignatureDeclaration>node).typeParameters, (<ConstructSignatureDeclaration>node).parameters, (<ConstructSignatureDeclaration>node).type, (<ConstructSignatureDeclaration>node).questionToken, location, flags);
break;
case SyntaxKind.IndexSignature:
return createIndexSignature((<IndexSignatureDeclaration>node).decorators, (<IndexSignatureDeclaration>node).modifiers, (<IndexSignatureDeclaration>node).parameters, (<IndexSignatureDeclaration>node).type, (<IndexSignatureDeclaration>node).questionToken, location, flags);
clone = createIndexSignature((<IndexSignatureDeclaration>node).decorators, (<IndexSignatureDeclaration>node).modifiers, (<IndexSignatureDeclaration>node).parameters, (<IndexSignatureDeclaration>node).type, (<IndexSignatureDeclaration>node).questionToken, location, flags);
break;
case SyntaxKind.TypePredicate:
return createTypePredicate((<TypePredicateNode>node).parameterName, (<TypePredicateNode>node).type, location, flags);
clone = createTypePredicate((<TypePredicateNode>node).parameterName, (<TypePredicateNode>node).type, location, flags);
break;
case SyntaxKind.TypeReference:
return createTypeReference((<TypeReferenceNode>node).typeName, (<TypeReferenceNode>node).typeArguments, location, flags);
clone = createTypeReference((<TypeReferenceNode>node).typeName, (<TypeReferenceNode>node).typeArguments, location, flags);
break;
case SyntaxKind.FunctionType:
return createFunctionType((<FunctionTypeNode>node).typeParameters, (<FunctionTypeNode>node).parameters, (<FunctionTypeNode>node).type, location, flags);
clone = createFunctionType((<FunctionTypeNode>node).typeParameters, (<FunctionTypeNode>node).parameters, (<FunctionTypeNode>node).type, location, flags);
break;
case SyntaxKind.ConstructorType:
return createConstructorType((<ConstructorTypeNode>node).typeParameters, (<ConstructorTypeNode>node).parameters, (<ConstructorTypeNode>node).type, location, flags);
clone = createConstructorType((<ConstructorTypeNode>node).typeParameters, (<ConstructorTypeNode>node).parameters, (<ConstructorTypeNode>node).type, location, flags);
break;
case SyntaxKind.TypeQuery:
return createTypeQuery((<TypeQueryNode>node).exprName, location, flags);
clone = createTypeQuery((<TypeQueryNode>node).exprName, location, flags);
break;
case SyntaxKind.TypeLiteral:
return createTypeLiteral((<TypeLiteralNode>node).members, location, flags);
clone = createTypeLiteral((<TypeLiteralNode>node).members, location, flags);
break;
case SyntaxKind.ArrayType:
return createArrayType((<ArrayTypeNode>node).elementType, location, flags);
clone = createArrayType((<ArrayTypeNode>node).elementType, location, flags);
break;
case SyntaxKind.TupleType:
return createTupleType((<TupleTypeNode>node).elementTypes, location, flags);
clone = createTupleType((<TupleTypeNode>node).elementTypes, location, flags);
break;
case SyntaxKind.UnionType:
return createUnionType((<UnionTypeNode>node).types, location, flags);
clone = createUnionType((<UnionTypeNode>node).types, location, flags);
break;
case SyntaxKind.IntersectionType:
return createIntersectionType((<IntersectionTypeNode>node).types, location, flags);
clone = createIntersectionType((<IntersectionTypeNode>node).types, location, flags);
break;
case SyntaxKind.ParenthesizedType:
return createParenthesizedType((<ParenthesizedTypeNode>node).type, location, flags);
clone = createParenthesizedType((<ParenthesizedTypeNode>node).type, location, flags);
break;
case SyntaxKind.ObjectBindingPattern:
return createObjectBindingPattern((<ObjectBindingPattern>node).elements, location, flags);
clone = createObjectBindingPattern((<ObjectBindingPattern>node).elements, location, flags);
break;
case SyntaxKind.ArrayBindingPattern:
return createArrayBindingPattern((<ArrayBindingPattern>node).elements, location, flags);
clone = createArrayBindingPattern((<ArrayBindingPattern>node).elements, location, flags);
break;
case SyntaxKind.BindingElement:
return createBindingElement((<BindingElement>node).propertyName, (<BindingElement>node).dotDotDotToken, (<BindingElement>node).name, (<BindingElement>node).initializer, location, flags);
clone = createBindingElement((<BindingElement>node).propertyName, (<BindingElement>node).dotDotDotToken, (<BindingElement>node).name, (<BindingElement>node).initializer, location, flags);
break;
case SyntaxKind.ArrayLiteralExpression:
return createArrayLiteralExpression((<ArrayLiteralExpression>node).elements, location, flags);
clone = createArrayLiteralExpression((<ArrayLiteralExpression>node).elements, location, flags);
break;
case SyntaxKind.ObjectLiteralExpression:
return createObjectLiteralExpression((<ObjectLiteralExpression>node).properties, location, flags);
clone = createObjectLiteralExpression((<ObjectLiteralExpression>node).properties, location, flags);
break;
case SyntaxKind.PropertyAccessExpression:
return createPropertyAccessExpression((<PropertyAccessExpression>node).expression, (<PropertyAccessExpression>node).dotToken, (<PropertyAccessExpression>node).name, location, flags);
clone = createPropertyAccessExpression((<PropertyAccessExpression>node).expression, (<PropertyAccessExpression>node).dotToken, (<PropertyAccessExpression>node).name, location, flags);
break;
case SyntaxKind.ElementAccessExpression:
return createElementAccessExpression((<ElementAccessExpression>node).expression, (<ElementAccessExpression>node).argumentExpression, location, flags);
clone = createElementAccessExpression((<ElementAccessExpression>node).expression, (<ElementAccessExpression>node).argumentExpression, location, flags);
break;
case SyntaxKind.CallExpression:
return createCallExpression((<CallExpression>node).expression, (<CallExpression>node).typeArguments, (<CallExpression>node).arguments, location, flags);
clone = createCallExpression((<CallExpression>node).expression, (<CallExpression>node).typeArguments, (<CallExpression>node).arguments, location, flags);
break;
case SyntaxKind.NewExpression:
return createNewExpression((<NewExpression>node).expression, (<NewExpression>node).typeArguments, (<NewExpression>node).arguments, location, flags);
clone = createNewExpression((<NewExpression>node).expression, (<NewExpression>node).typeArguments, (<NewExpression>node).arguments, location, flags);
break;
case SyntaxKind.TaggedTemplateExpression:
return createTaggedTemplateExpression((<TaggedTemplateExpression>node).tag, (<TaggedTemplateExpression>node).template, location, flags);
clone = createTaggedTemplateExpression((<TaggedTemplateExpression>node).tag, (<TaggedTemplateExpression>node).template, location, flags);
break;
case SyntaxKind.TypeAssertionExpression:
return createTypeAssertionExpression((<TypeAssertion>node).type, (<TypeAssertion>node).expression, location, flags);
clone = createTypeAssertionExpression((<TypeAssertion>node).type, (<TypeAssertion>node).expression, location, flags);
break;
case SyntaxKind.ParenthesizedExpression:
return createParenthesizedExpression((<ParenthesizedExpression>node).expression, location, flags);
clone = createParenthesizedExpression((<ParenthesizedExpression>node).expression, location, flags);
break;
case SyntaxKind.FunctionExpression:
return createFunctionExpression((<FunctionExpression>node).decorators, (<FunctionExpression>node).modifiers, (<FunctionExpression>node).asteriskToken, (<FunctionExpression>node).name, (<FunctionExpression>node).typeParameters, (<FunctionExpression>node).parameters, (<FunctionExpression>node).type, (<FunctionExpression>node).body, location, flags);
clone = createFunctionExpression((<FunctionExpression>node).decorators, (<FunctionExpression>node).modifiers, (<FunctionExpression>node).asteriskToken, (<FunctionExpression>node).name, (<FunctionExpression>node).typeParameters, (<FunctionExpression>node).parameters, (<FunctionExpression>node).type, (<FunctionExpression>node).body, location, flags);
break;
case SyntaxKind.ArrowFunction:
return createArrowFunction((<ArrowFunction>node).decorators, (<ArrowFunction>node).modifiers, (<ArrowFunction>node).typeParameters, (<ArrowFunction>node).parameters, (<ArrowFunction>node).type, (<ArrowFunction>node).equalsGreaterThanToken, (<ArrowFunction>node).body, location, flags);
clone = createArrowFunction((<ArrowFunction>node).decorators, (<ArrowFunction>node).modifiers, (<ArrowFunction>node).typeParameters, (<ArrowFunction>node).parameters, (<ArrowFunction>node).type, (<ArrowFunction>node).equalsGreaterThanToken, (<ArrowFunction>node).body, location, flags);
break;
case SyntaxKind.DeleteExpression:
return createDeleteExpression((<DeleteExpression>node).expression, location, flags);
clone = createDeleteExpression((<DeleteExpression>node).expression, location, flags);
break;
case SyntaxKind.TypeOfExpression:
return createTypeOfExpression((<TypeOfExpression>node).expression, location, flags);
clone = createTypeOfExpression((<TypeOfExpression>node).expression, location, flags);
break;
case SyntaxKind.VoidExpression:
return createVoidExpression((<VoidExpression>node).expression, location, flags);
clone = createVoidExpression((<VoidExpression>node).expression, location, flags);
break;
case SyntaxKind.AwaitExpression:
return createAwaitExpression((<AwaitExpression>node).expression, location, flags);
clone = createAwaitExpression((<AwaitExpression>node).expression, location, flags);
break;
case SyntaxKind.PrefixUnaryExpression:
return createPrefixUnaryExpression((<PrefixUnaryExpression>node).operator, (<PrefixUnaryExpression>node).operand, location, flags);
clone = createPrefixUnaryExpression((<PrefixUnaryExpression>node).operator, (<PrefixUnaryExpression>node).operand, location, flags);
break;
case SyntaxKind.PostfixUnaryExpression:
return createPostfixUnaryExpression((<PostfixUnaryExpression>node).operand, (<PostfixUnaryExpression>node).operator, location, flags);
clone = createPostfixUnaryExpression((<PostfixUnaryExpression>node).operand, (<PostfixUnaryExpression>node).operator, location, flags);
break;
case SyntaxKind.BinaryExpression:
return createBinaryExpression((<BinaryExpression>node).left, (<BinaryExpression>node).operatorToken, (<BinaryExpression>node).right, location, flags);
clone = createBinaryExpression((<BinaryExpression>node).left, (<BinaryExpression>node).operatorToken, (<BinaryExpression>node).right, location, flags);
break;
case SyntaxKind.ConditionalExpression:
return createConditionalExpression((<ConditionalExpression>node).condition, (<ConditionalExpression>node).questionToken, (<ConditionalExpression>node).whenTrue, (<ConditionalExpression>node).colonToken, (<ConditionalExpression>node).whenFalse, location, flags);
clone = createConditionalExpression((<ConditionalExpression>node).condition, (<ConditionalExpression>node).questionToken, (<ConditionalExpression>node).whenTrue, (<ConditionalExpression>node).colonToken, (<ConditionalExpression>node).whenFalse, location, flags);
break;
case SyntaxKind.TemplateExpression:
return createTemplateExpression((<TemplateExpression>node).head, (<TemplateExpression>node).templateSpans, location, flags);
clone = createTemplateExpression((<TemplateExpression>node).head, (<TemplateExpression>node).templateSpans, location, flags);
break;
case SyntaxKind.YieldExpression:
return createYieldExpression((<YieldExpression>node).asteriskToken, (<YieldExpression>node).expression, location, flags);
clone = createYieldExpression((<YieldExpression>node).asteriskToken, (<YieldExpression>node).expression, location, flags);
break;
case SyntaxKind.SpreadElementExpression:
return createSpreadElementExpression((<SpreadElementExpression>node).expression, location, flags);
clone = createSpreadElementExpression((<SpreadElementExpression>node).expression, location, flags);
break;
case SyntaxKind.ClassExpression:
return createClassExpression((<ClassExpression>node).decorators, (<ClassExpression>node).modifiers, (<ClassExpression>node).name, (<ClassExpression>node).typeParameters, (<ClassExpression>node).heritageClauses, (<ClassExpression>node).members, location, flags);
clone = createClassExpression((<ClassExpression>node).decorators, (<ClassExpression>node).modifiers, (<ClassExpression>node).name, (<ClassExpression>node).typeParameters, (<ClassExpression>node).heritageClauses, (<ClassExpression>node).members, location, flags);
break;
case SyntaxKind.OmittedExpression:
return createOmittedExpression(location, flags);
clone = createOmittedExpression(location, flags);
break;
case SyntaxKind.ExpressionWithTypeArguments:
return createExpressionWithTypeArguments((<ExpressionWithTypeArguments>node).expression, (<ExpressionWithTypeArguments>node).typeArguments, location, flags);
clone = createExpressionWithTypeArguments((<ExpressionWithTypeArguments>node).expression, (<ExpressionWithTypeArguments>node).typeArguments, location, flags);
break;
case SyntaxKind.AsExpression:
return createAsExpression((<AsExpression>node).expression, (<AsExpression>node).type, location, flags);
clone = createAsExpression((<AsExpression>node).expression, (<AsExpression>node).type, location, flags);
break;
case SyntaxKind.TemplateSpan:
return createTemplateSpan((<TemplateSpan>node).expression, (<TemplateSpan>node).literal, location, flags);
clone = createTemplateSpan((<TemplateSpan>node).expression, (<TemplateSpan>node).literal, location, flags);
break;
case SyntaxKind.SemicolonClassElement:
return createSemicolonClassElement(location, flags);
clone = createSemicolonClassElement(location, flags);
break;
case SyntaxKind.Block:
return createBlock((<Block>node).statements, location, flags);
clone = createBlock((<Block>node).statements, location, flags);
break;
case SyntaxKind.VariableStatement:
return createVariableStatement((<VariableStatement>node).decorators, (<VariableStatement>node).modifiers, (<VariableStatement>node).declarationList, location, flags);
clone = createVariableStatement((<VariableStatement>node).decorators, (<VariableStatement>node).modifiers, (<VariableStatement>node).declarationList, location, flags);
break;
case SyntaxKind.EmptyStatement:
return createEmptyStatement(location, flags);
clone = createEmptyStatement(location, flags);
break;
case SyntaxKind.ExpressionStatement:
return createExpressionStatement((<ExpressionStatement>node).expression, location, flags);
clone = createExpressionStatement((<ExpressionStatement>node).expression, location, flags);
break;
case SyntaxKind.IfStatement:
return createIfStatement((<IfStatement>node).expression, (<IfStatement>node).thenStatement, (<IfStatement>node).elseStatement, location, flags);
clone = createIfStatement((<IfStatement>node).expression, (<IfStatement>node).thenStatement, (<IfStatement>node).elseStatement, location, flags);
break;
case SyntaxKind.DoStatement:
return createDoStatement((<DoStatement>node).statement, (<DoStatement>node).expression, location, flags);
clone = createDoStatement((<DoStatement>node).statement, (<DoStatement>node).expression, location, flags);
break;
case SyntaxKind.WhileStatement:
return createWhileStatement((<WhileStatement>node).expression, (<WhileStatement>node).statement, location, flags);
clone = createWhileStatement((<WhileStatement>node).expression, (<WhileStatement>node).statement, location, flags);
break;
case SyntaxKind.ForStatement:
return createForStatement((<ForStatement>node).initializer, (<ForStatement>node).condition, (<ForStatement>node).incrementor, (<ForStatement>node).statement, location, flags);
clone = createForStatement((<ForStatement>node).initializer, (<ForStatement>node).condition, (<ForStatement>node).incrementor, (<ForStatement>node).statement, location, flags);
break;
case SyntaxKind.ForInStatement:
return createForInStatement((<ForInStatement>node).initializer, (<ForInStatement>node).expression, (<ForInStatement>node).statement, location, flags);
clone = createForInStatement((<ForInStatement>node).initializer, (<ForInStatement>node).expression, (<ForInStatement>node).statement, location, flags);
break;
case SyntaxKind.ForOfStatement:
return createForOfStatement((<ForOfStatement>node).initializer, (<ForOfStatement>node).expression, (<ForOfStatement>node).statement, location, flags);
clone = createForOfStatement((<ForOfStatement>node).initializer, (<ForOfStatement>node).expression, (<ForOfStatement>node).statement, location, flags);
break;
case SyntaxKind.ContinueStatement:
return createContinueStatement((<ContinueStatement>node).label, location, flags);
clone = createContinueStatement((<ContinueStatement>node).label, location, flags);
break;
case SyntaxKind.BreakStatement:
return createBreakStatement((<BreakStatement>node).label, location, flags);
clone = createBreakStatement((<BreakStatement>node).label, location, flags);
break;
case SyntaxKind.ReturnStatement:
return createReturnStatement((<ReturnStatement>node).expression, location, flags);
clone = createReturnStatement((<ReturnStatement>node).expression, location, flags);
break;
case SyntaxKind.WithStatement:
return createWithStatement((<WithStatement>node).expression, (<WithStatement>node).statement, location, flags);
clone = createWithStatement((<WithStatement>node).expression, (<WithStatement>node).statement, location, flags);
break;
case SyntaxKind.SwitchStatement:
return createSwitchStatement((<SwitchStatement>node).expression, (<SwitchStatement>node).caseBlock, location, flags);
clone = createSwitchStatement((<SwitchStatement>node).expression, (<SwitchStatement>node).caseBlock, location, flags);
break;
case SyntaxKind.LabeledStatement:
return createLabeledStatement((<LabeledStatement>node).label, (<LabeledStatement>node).statement, location, flags);
clone = createLabeledStatement((<LabeledStatement>node).label, (<LabeledStatement>node).statement, location, flags);
break;
case SyntaxKind.ThrowStatement:
return createThrowStatement((<ThrowStatement>node).expression, location, flags);
clone = createThrowStatement((<ThrowStatement>node).expression, location, flags);
break;
case SyntaxKind.TryStatement:
return createTryStatement((<TryStatement>node).tryBlock, (<TryStatement>node).catchClause, (<TryStatement>node).finallyBlock, location, flags);
clone = createTryStatement((<TryStatement>node).tryBlock, (<TryStatement>node).catchClause, (<TryStatement>node).finallyBlock, location, flags);
break;
case SyntaxKind.DebuggerStatement:
return createDebuggerStatement(location, flags);
clone = createDebuggerStatement(location, flags);
break;
case SyntaxKind.VariableDeclaration:
return createVariableDeclaration((<VariableDeclaration>node).name, (<VariableDeclaration>node).type, (<VariableDeclaration>node).initializer, location, flags);
clone = createVariableDeclaration((<VariableDeclaration>node).name, (<VariableDeclaration>node).type, (<VariableDeclaration>node).initializer, location, flags);
break;
case SyntaxKind.VariableDeclarationList:
return createVariableDeclarationList((<VariableDeclarationList>node).declarations, location, flags);
clone = createVariableDeclarationList((<VariableDeclarationList>node).declarations, location, flags);
break;
case SyntaxKind.FunctionDeclaration:
return createFunctionDeclaration((<FunctionDeclaration>node).decorators, (<FunctionDeclaration>node).modifiers, (<FunctionDeclaration>node).asteriskToken, (<FunctionDeclaration>node).name, (<FunctionDeclaration>node).typeParameters, (<FunctionDeclaration>node).parameters, (<FunctionDeclaration>node).type, (<FunctionDeclaration>node).body, location, flags);
clone = createFunctionDeclaration((<FunctionDeclaration>node).decorators, (<FunctionDeclaration>node).modifiers, (<FunctionDeclaration>node).asteriskToken, (<FunctionDeclaration>node).name, (<FunctionDeclaration>node).typeParameters, (<FunctionDeclaration>node).parameters, (<FunctionDeclaration>node).type, (<FunctionDeclaration>node).body, location, flags);
break;
case SyntaxKind.ClassDeclaration:
return createClassDeclaration((<ClassDeclaration>node).decorators, (<ClassDeclaration>node).modifiers, (<ClassDeclaration>node).name, (<ClassDeclaration>node).typeParameters, (<ClassDeclaration>node).heritageClauses, (<ClassDeclaration>node).members, location, flags);
clone = createClassDeclaration((<ClassDeclaration>node).decorators, (<ClassDeclaration>node).modifiers, (<ClassDeclaration>node).name, (<ClassDeclaration>node).typeParameters, (<ClassDeclaration>node).heritageClauses, (<ClassDeclaration>node).members, location, flags);
break;
case SyntaxKind.InterfaceDeclaration:
return createInterfaceDeclaration((<InterfaceDeclaration>node).decorators, (<InterfaceDeclaration>node).modifiers, (<InterfaceDeclaration>node).name, (<InterfaceDeclaration>node).typeParameters, (<InterfaceDeclaration>node).heritageClauses, (<InterfaceDeclaration>node).members, location, flags);
clone = createInterfaceDeclaration((<InterfaceDeclaration>node).decorators, (<InterfaceDeclaration>node).modifiers, (<InterfaceDeclaration>node).name, (<InterfaceDeclaration>node).typeParameters, (<InterfaceDeclaration>node).heritageClauses, (<InterfaceDeclaration>node).members, location, flags);
break;
case SyntaxKind.TypeAliasDeclaration:
return createTypeAliasDeclaration((<TypeAliasDeclaration>node).decorators, (<TypeAliasDeclaration>node).modifiers, (<TypeAliasDeclaration>node).name, (<TypeAliasDeclaration>node).typeParameters, (<TypeAliasDeclaration>node).type, location, flags);
clone = createTypeAliasDeclaration((<TypeAliasDeclaration>node).decorators, (<TypeAliasDeclaration>node).modifiers, (<TypeAliasDeclaration>node).name, (<TypeAliasDeclaration>node).typeParameters, (<TypeAliasDeclaration>node).type, location, flags);
break;
case SyntaxKind.EnumDeclaration:
return createEnumDeclaration((<EnumDeclaration>node).decorators, (<EnumDeclaration>node).modifiers, (<EnumDeclaration>node).name, (<EnumDeclaration>node).members, location, flags);
clone = createEnumDeclaration((<EnumDeclaration>node).decorators, (<EnumDeclaration>node).modifiers, (<EnumDeclaration>node).name, (<EnumDeclaration>node).members, location, flags);
break;
case SyntaxKind.ModuleDeclaration:
return createModuleDeclaration((<ModuleDeclaration>node).decorators, (<ModuleDeclaration>node).modifiers, (<ModuleDeclaration>node).name, (<ModuleDeclaration>node).body, location, flags);
clone = createModuleDeclaration((<ModuleDeclaration>node).decorators, (<ModuleDeclaration>node).modifiers, (<ModuleDeclaration>node).name, (<ModuleDeclaration>node).body, location, flags);
break;
case SyntaxKind.ModuleBlock:
return createModuleBlock((<ModuleBlock>node).statements, location, flags);
clone = createModuleBlock((<ModuleBlock>node).statements, location, flags);
break;
case SyntaxKind.CaseBlock:
return createCaseBlock((<CaseBlock>node).clauses, location, flags);
clone = createCaseBlock((<CaseBlock>node).clauses, location, flags);
break;
case SyntaxKind.ImportEqualsDeclaration:
return createImportEqualsDeclaration((<ImportEqualsDeclaration>node).decorators, (<ImportEqualsDeclaration>node).modifiers, (<ImportEqualsDeclaration>node).name, (<ImportEqualsDeclaration>node).moduleReference, location, flags);
clone = createImportEqualsDeclaration((<ImportEqualsDeclaration>node).decorators, (<ImportEqualsDeclaration>node).modifiers, (<ImportEqualsDeclaration>node).name, (<ImportEqualsDeclaration>node).moduleReference, location, flags);
break;
case SyntaxKind.ImportDeclaration:
return createImportDeclaration((<ImportDeclaration>node).decorators, (<ImportDeclaration>node).modifiers, (<ImportDeclaration>node).importClause, (<ImportDeclaration>node).moduleSpecifier, location, flags);
clone = createImportDeclaration((<ImportDeclaration>node).decorators, (<ImportDeclaration>node).modifiers, (<ImportDeclaration>node).importClause, (<ImportDeclaration>node).moduleSpecifier, location, flags);
break;
case SyntaxKind.ImportClause:
return createImportClause((<ImportClause>node).name, (<ImportClause>node).namedBindings, location, flags);
clone = createImportClause((<ImportClause>node).name, (<ImportClause>node).namedBindings, location, flags);
break;
case SyntaxKind.NamespaceImport:
return createNamespaceImport((<NamespaceImport>node).name, location, flags);
clone = createNamespaceImport((<NamespaceImport>node).name, location, flags);
break;
case SyntaxKind.NamedImports:
return createNamedImports((<NamedImports>node).elements, location, flags);
clone = createNamedImports((<NamedImports>node).elements, location, flags);
break;
case SyntaxKind.ImportSpecifier:
return createImportSpecifier((<ImportSpecifier>node).propertyName, (<ImportSpecifier>node).name, location, flags);
clone = createImportSpecifier((<ImportSpecifier>node).propertyName, (<ImportSpecifier>node).name, location, flags);
break;
case SyntaxKind.ExportAssignment:
return createExportAssignment((<ExportAssignment>node).decorators, (<ExportAssignment>node).modifiers, (<ExportAssignment>node).expression, location, flags);
clone = createExportAssignment((<ExportAssignment>node).decorators, (<ExportAssignment>node).modifiers, (<ExportAssignment>node).expression, location, flags);
break;
case SyntaxKind.ExportDeclaration:
return createExportDeclaration((<ExportDeclaration>node).decorators, (<ExportDeclaration>node).modifiers, (<ExportDeclaration>node).exportClause, (<ExportDeclaration>node).moduleSpecifier, location, flags);
clone = createExportDeclaration((<ExportDeclaration>node).decorators, (<ExportDeclaration>node).modifiers, (<ExportDeclaration>node).exportClause, (<ExportDeclaration>node).moduleSpecifier, location, flags);
break;
case SyntaxKind.NamedExports:
return createNamedExports((<NamedExports>node).elements, location, flags);
clone = createNamedExports((<NamedExports>node).elements, location, flags);
break;
case SyntaxKind.ExportSpecifier:
return createExportSpecifier((<ExportSpecifier>node).propertyName, (<ExportSpecifier>node).name, location, flags);
clone = createExportSpecifier((<ExportSpecifier>node).propertyName, (<ExportSpecifier>node).name, location, flags);
break;
case SyntaxKind.MissingDeclaration:
return createMissingDeclaration((<MissingDeclaration>node).decorators, (<MissingDeclaration>node).modifiers, (<MissingDeclaration>node).questionToken, location, flags);
clone = createMissingDeclaration((<MissingDeclaration>node).decorators, (<MissingDeclaration>node).modifiers, (<MissingDeclaration>node).questionToken, location, flags);
break;
case SyntaxKind.ExternalModuleReference:
return createExternalModuleReference((<ExternalModuleReference>node).expression, location, flags);
clone = createExternalModuleReference((<ExternalModuleReference>node).expression, location, flags);
break;
case SyntaxKind.JsxElement:
return createJsxElement((<JsxElement>node).openingElement, (<JsxElement>node).children, (<JsxElement>node).closingElement, location, flags);
clone = createJsxElement((<JsxElement>node).openingElement, (<JsxElement>node).children, (<JsxElement>node).closingElement, location, flags);
break;
case SyntaxKind.JsxSelfClosingElement:
return createJsxSelfClosingElement((<JsxSelfClosingElement>node).tagName, (<JsxSelfClosingElement>node).attributes, location, flags);
clone = createJsxSelfClosingElement((<JsxSelfClosingElement>node).tagName, (<JsxSelfClosingElement>node).attributes, location, flags);
break;
case SyntaxKind.JsxOpeningElement:
return createJsxOpeningElement((<JsxOpeningElement>node).tagName, (<JsxOpeningElement>node).attributes, location, flags);
clone = createJsxOpeningElement((<JsxOpeningElement>node).tagName, (<JsxOpeningElement>node).attributes, location, flags);
break;
case SyntaxKind.JsxText:
return createJsxText(location, flags);
clone = createJsxText(location, flags);
break;
case SyntaxKind.JsxClosingElement:
return createJsxClosingElement((<JsxClosingElement>node).tagName, location, flags);
clone = createJsxClosingElement((<JsxClosingElement>node).tagName, location, flags);
break;
case SyntaxKind.JsxAttribute:
return createJsxAttribute((<JsxAttribute>node).name, (<JsxAttribute>node).initializer, location, flags);
clone = createJsxAttribute((<JsxAttribute>node).name, (<JsxAttribute>node).initializer, location, flags);
break;
case SyntaxKind.JsxSpreadAttribute:
return createJsxSpreadAttribute((<JsxSpreadAttribute>node).expression, location, flags);
clone = createJsxSpreadAttribute((<JsxSpreadAttribute>node).expression, location, flags);
break;
case SyntaxKind.JsxExpression:
return createJsxExpression((<JsxExpression>node).expression, location, flags);
clone = createJsxExpression((<JsxExpression>node).expression, location, flags);
break;
case SyntaxKind.CaseClause:
return createCaseClause((<CaseClause>node).expression, (<CaseClause>node).statements, location, flags);
clone = createCaseClause((<CaseClause>node).expression, (<CaseClause>node).statements, location, flags);
break;
case SyntaxKind.DefaultClause:
return createDefaultClause((<DefaultClause>node).statements, location, flags);
clone = createDefaultClause((<DefaultClause>node).statements, location, flags);
break;
case SyntaxKind.HeritageClause:
return createHeritageClause((<HeritageClause>node).token, (<HeritageClause>node).types, location, flags);
clone = createHeritageClause((<HeritageClause>node).token, (<HeritageClause>node).types, location, flags);
break;
case SyntaxKind.CatchClause:
return createCatchClause((<CatchClause>node).variableDeclaration, (<CatchClause>node).block, location, flags);
clone = createCatchClause((<CatchClause>node).variableDeclaration, (<CatchClause>node).block, location, flags);
break;
case SyntaxKind.PropertyAssignment:
return createPropertyAssignment((<PropertyAssignment>node).name, (<PropertyAssignment>node).initializer, location, flags);
clone = createPropertyAssignment((<PropertyAssignment>node).name, (<PropertyAssignment>node).initializer, location, flags);
break;
case SyntaxKind.ShorthandPropertyAssignment:
return createShorthandPropertyAssignment((<ShorthandPropertyAssignment>node).name, (<ShorthandPropertyAssignment>node).equalsToken, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer, location, flags);
clone = createShorthandPropertyAssignment((<ShorthandPropertyAssignment>node).name, location, flags);
break;
case SyntaxKind.EnumMember:
return createEnumMember((<EnumMember>node).name, (<EnumMember>node).initializer, location, flags);
clone = createEnumMember((<EnumMember>node).name, (<EnumMember>node).initializer, location, flags);
break;
case SyntaxKind.SourceFile:
return createSourceFileNode((<SourceFile>node).statements, (<SourceFile>node).endOfFileToken, (<SourceFile>node).fileName, (<SourceFile>node).text, (<SourceFile>node).amdDependencies, (<SourceFile>node).moduleName, (<SourceFile>node).referencedFiles, (<SourceFile>node).languageVariant, (<SourceFile>node).renamedDependencies, (<SourceFile>node).hasNoDefaultLib, (<SourceFile>node).languageVersion, (<SourceFile>node).externalModuleIndicator, (<SourceFile>node).isDefaultLib, (<SourceFile>node).identifiers, (<SourceFile>node).parseDiagnostics, (<SourceFile>node).bindDiagnostics, (<SourceFile>node).lineMap, (<SourceFile>node).classifiableNames, (<SourceFile>node).resolvedModules, (<SourceFile>node).imports, location, flags);
clone = createSourceFileNode((<SourceFile>node).statements, (<SourceFile>node).endOfFileToken, (<SourceFile>node).fileName, (<SourceFile>node).text, (<SourceFile>node).amdDependencies, (<SourceFile>node).moduleName, (<SourceFile>node).referencedFiles, (<SourceFile>node).languageVariant, (<SourceFile>node).renamedDependencies, (<SourceFile>node).hasNoDefaultLib, (<SourceFile>node).languageVersion, (<SourceFile>node).externalModuleIndicator, (<SourceFile>node).isDefaultLib, (<SourceFile>node).identifiers, (<SourceFile>node).parseDiagnostics, (<SourceFile>node).bindDiagnostics, (<SourceFile>node).lineMap, (<SourceFile>node).classifiableNames, (<SourceFile>node).resolvedModules, (<SourceFile>node).imports, location, flags);
break;
case SyntaxKind.JSDocTypeExpression:
return createJSDocTypeExpression((<JSDocTypeExpression>node).type, location, flags);
clone = createJSDocTypeExpression((<JSDocTypeExpression>node).type, location, flags);
break;
case SyntaxKind.JSDocAllType:
return createJSDocAllType(location, flags);
clone = createJSDocAllType(location, flags);
break;
case SyntaxKind.JSDocUnknownType:
return createJSDocUnknownType(location, flags);
clone = createJSDocUnknownType(location, flags);
break;
case SyntaxKind.JSDocArrayType:
return createJSDocArrayType((<JSDocArrayType>node).elementType, location, flags);
clone = createJSDocArrayType((<JSDocArrayType>node).elementType, location, flags);
break;
case SyntaxKind.JSDocUnionType:
return createJSDocUnionType((<JSDocUnionType>node).types, location, flags);
clone = createJSDocUnionType((<JSDocUnionType>node).types, location, flags);
break;
case SyntaxKind.JSDocTupleType:
return createJSDocTupleType((<JSDocTupleType>node).types, location, flags);
clone = createJSDocTupleType((<JSDocTupleType>node).types, location, flags);
break;
case SyntaxKind.JSDocNullableType:
return createJSDocNullableType((<JSDocNullableType>node).type, location, flags);
clone = createJSDocNullableType((<JSDocNullableType>node).type, location, flags);
break;
case SyntaxKind.JSDocNonNullableType:
return createJSDocNonNullableType((<JSDocNonNullableType>node).type, location, flags);
clone = createJSDocNonNullableType((<JSDocNonNullableType>node).type, location, flags);
break;
case SyntaxKind.JSDocRecordType:
return createJSDocRecordType((<JSDocRecordType>node).members, location, flags);
clone = createJSDocRecordType((<JSDocRecordType>node).members, location, flags);
break;
case SyntaxKind.JSDocRecordMember:
return createJSDocRecordMember((<JSDocRecordMember>node).name, (<JSDocRecordMember>node).type, location, flags);
clone = createJSDocRecordMember((<JSDocRecordMember>node).name, (<JSDocRecordMember>node).type, location, flags);
break;
case SyntaxKind.JSDocTypeReference:
return createJSDocTypeReference((<JSDocTypeReference>node).name, (<JSDocTypeReference>node).typeArguments, location, flags);
clone = createJSDocTypeReference((<JSDocTypeReference>node).name, (<JSDocTypeReference>node).typeArguments, location, flags);
break;
case SyntaxKind.JSDocOptionalType:
return createJSDocOptionalType((<JSDocOptionalType>node).type, location, flags);
clone = createJSDocOptionalType((<JSDocOptionalType>node).type, location, flags);
break;
case SyntaxKind.JSDocFunctionType:
return createJSDocFunctionType((<JSDocFunctionType>node).parameters, (<JSDocFunctionType>node).type, location, flags);
clone = createJSDocFunctionType((<JSDocFunctionType>node).parameters, (<JSDocFunctionType>node).type, location, flags);
break;
case SyntaxKind.JSDocVariadicType:
return createJSDocVariadicType((<JSDocVariadicType>node).type, location, flags);
clone = createJSDocVariadicType((<JSDocVariadicType>node).type, location, flags);
break;
case SyntaxKind.JSDocConstructorType:
return createJSDocConstructorType((<JSDocConstructorType>node).type, location, flags);
clone = createJSDocConstructorType((<JSDocConstructorType>node).type, location, flags);
break;
case SyntaxKind.JSDocThisType:
return createJSDocThisType((<JSDocThisType>node).type, location, flags);
clone = createJSDocThisType((<JSDocThisType>node).type, location, flags);
break;
case SyntaxKind.JSDocComment:
return createJSDocComment((<JSDocComment>node).tags, location, flags);
clone = createJSDocComment((<JSDocComment>node).tags, location, flags);
break;
case SyntaxKind.JSDocTag:
return createJSDocTag((<JSDocTag>node).atToken, (<JSDocTag>node).tagName, location, flags);
clone = createJSDocTag((<JSDocTag>node).atToken, (<JSDocTag>node).tagName, location, flags);
break;
case SyntaxKind.JSDocParameterTag:
return createJSDocParameterTag((<JSDocParameterTag>node).preParameterName, (<JSDocParameterTag>node).typeExpression, (<JSDocParameterTag>node).postParameterName, (<JSDocParameterTag>node).atToken, (<JSDocParameterTag>node).tagName, location, flags);
clone = createJSDocParameterTag((<JSDocParameterTag>node).preParameterName, (<JSDocParameterTag>node).typeExpression, (<JSDocParameterTag>node).postParameterName, (<JSDocParameterTag>node).atToken, (<JSDocParameterTag>node).tagName, location, flags);
break;
case SyntaxKind.JSDocReturnTag:
return createJSDocReturnTag((<JSDocReturnTag>node).typeExpression, (<JSDocReturnTag>node).atToken, (<JSDocReturnTag>node).tagName, location, flags);
clone = createJSDocReturnTag((<JSDocReturnTag>node).typeExpression, (<JSDocReturnTag>node).atToken, (<JSDocReturnTag>node).tagName, location, flags);
break;
case SyntaxKind.JSDocTypeTag:
return createJSDocTypeTag((<JSDocTypeTag>node).typeExpression, (<JSDocTypeTag>node).atToken, (<JSDocTypeTag>node).tagName, location, flags);
clone = createJSDocTypeTag((<JSDocTypeTag>node).typeExpression, (<JSDocTypeTag>node).atToken, (<JSDocTypeTag>node).tagName, location, flags);
break;
case SyntaxKind.JSDocTemplateTag:
return createJSDocTemplateTag((<JSDocTemplateTag>node).typeParameters, (<JSDocTemplateTag>node).atToken, (<JSDocTemplateTag>node).tagName, location, flags);
clone = createJSDocTemplateTag((<JSDocTemplateTag>node).typeParameters, (<JSDocTemplateTag>node).atToken, (<JSDocTemplateTag>node).tagName, location, flags);
break;
case SyntaxKind.RawExpression:
return createRawExpression((<RawExpression>node).text, location, flags);
clone = createRawExpression((<RawExpression>node).text, location, flags);
break;
case SyntaxKind.RawStatement:
return createRawStatement((<RawStatement>node).text, location, flags);
clone = createRawStatement((<RawStatement>node).text, location, flags);
break;
}
if (clone) {
clone.original = node;
return clone;
}
}
return node;
@ -3377,7 +3531,7 @@ namespace ts {
case SyntaxKind.PropertyAssignment:
return updatePropertyAssignment(<PropertyAssignment>node, transformer.visitNode((<PropertyAssignment>node).name, visitor, isPropertyName), transformer.visitNode((<PropertyAssignment>node).initializer, visitor, isExpressionNode));
case SyntaxKind.ShorthandPropertyAssignment:
return updateShorthandPropertyAssignment(<ShorthandPropertyAssignment>node, transformer.visitNode((<ShorthandPropertyAssignment>node).name, visitor, isIdentifier), (<ShorthandPropertyAssignment>node).equalsToken, transformer.visitNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, visitor, isExpressionNode));
return updateShorthandPropertyAssignment(<ShorthandPropertyAssignment>node, transformer.visitNode((<ShorthandPropertyAssignment>node).name, visitor, isIdentifier));
case SyntaxKind.EnumMember:
return updateEnumMember(<EnumMember>node, transformer.visitNode((<EnumMember>node).name, visitor, isDeclarationNameNode), transformer.visitNode((<EnumMember>node).initializer, visitor, isExpressionNode));
case SyntaxKind.SourceFile:

View File

@ -36,7 +36,9 @@ namespace ts {
}
export function setOriginalNode<T extends Node>(node: T, original: Node): T {
node.original = node;
if (node && node !== original) {
node.original = node;
}
return node;
}
@ -46,8 +48,8 @@ namespace ts {
return node;
}
export function startOnNewLine<T extends Node>(node: T): T {
(<SynthesizedNode>node).startsOnNewLine = true;
export function startOnNewLine<T extends Node>(node: T, value?: boolean): T {
(<SynthesizedNode>node).startsOnNewLine = value === undefined ? true : value;
return node;
}
@ -135,7 +137,7 @@ namespace ts {
return modifiers;
}
export function createNumericLiteral2(value: number, location?: TextRange, flags?: NodeFlags): LiteralExpression {
let node = createNumericLiteral(String(value), location, flags);
return node;
@ -234,8 +236,12 @@ namespace ts {
return createPropertyAssignment(createIdentifier(name), initializer);
}
export function createAssignmentExpression(left: Expression, right: Expression) {
return createBinaryExpression2(left, SyntaxKind.EqualsToken, right);
export function createAssignmentStatement(left: Expression, right: Expression, location?: TextRange) {
return createExpressionStatement(createAssignmentExpression(left, right), location);
}
export function createAssignmentExpression(left: Expression, right: Expression, location?: TextRange) {
return createBinaryExpression2(left, SyntaxKind.EqualsToken, right, location);
}
export function createStrictEqualityExpression(left: Expression, right: Expression) {
@ -246,6 +252,10 @@ namespace ts {
return createBinaryExpression2(left, SyntaxKind.ExclamationEqualsEqualsToken, right);
}
export function createLogicalNotExpression(operand: LeftHandSideExpression) {
return createPrefixUnaryExpression(SyntaxKind.ExclamationToken, operand);
}
export function createLogicalAndExpression(left: Expression, right: Expression) {
return createBinaryExpression2(left, SyntaxKind.AmpersandAmpersandToken, right);
}
@ -308,6 +318,10 @@ namespace ts {
return createVariableStatement2(varDeclList, location, flags & ~(NodeFlags.Let | NodeFlags.Const));
}
export function createVariableStatement4(name: string, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
return createVariableStatement3(createIdentifier(name), initializer, location, flags);
}
export function createLetStatement(name: Identifier, initializer: Expression, location?: TextRange, exported?: boolean) {
return createVariableStatement3(name, initializer, location, exported ? NodeFlags.Let | NodeFlags.Export : NodeFlags.Let);
}
@ -324,8 +338,8 @@ namespace ts {
return createClassDeclaration(undefined, undefined, name, undefined, createClassHeritageClauses(baseTypeNode), members, location, flags);
}
export function createClassExpression2(name: Identifier, baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[]): ClassExpression {
return createClassExpression(undefined, undefined, name, undefined, createClassHeritageClauses(baseTypeNode), members);
export function createClassExpression2(name: Identifier, baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[], location?: TextRange): ClassExpression {
return createClassExpression(undefined, undefined, name, undefined, createClassHeritageClauses(baseTypeNode), members, location);
}
export function createClassExpression3(baseTypeNode: ExpressionWithTypeArguments, members: ClassElement[]): ClassExpression {
@ -394,6 +408,17 @@ namespace ts {
return createElementAccessExpression2(expression, createNumericLiteral2(index), location, flags);
}
export function createObjectLiteralExpression2(propertyMap: Map<Expression>) {
let properties: PropertyAssignment[] = [];
for (let key in propertyMap) {
if (hasProperty(propertyMap, key)) {
properties.push(createPropertyAssignment2(key, propertyMap[key]));
}
}
return createObjectLiteralExpression(properties);
}
export function createConcatCall(value: Expression, _arguments: Expression[]) {
return createCallExpression2(createPropertyAccessExpression3(value, "concat"), _arguments);
}
@ -437,32 +462,93 @@ namespace ts {
return createCallExpression2(createIdentifier("__metadata"), [createStringLiteral(metadataKey), metadataValue]);
}
export function createHasOwnPropertyCall(target: LeftHandSideExpression, property: Expression) {
return createCallExpression2(createPropertyAccessExpression3(target, "hasOwnProperty"), [property]);
}
export function createExportStarHelperCall(moduleValue: Expression) {
return createCallExpression2(createIdentifier("__export"), [moduleValue]);
}
export const enum PropertyDescriptorFlags {
Empty = 0,
Enumerable = 1 << 0,
NotEnumerable = 1 << 1,
Configurable = 1 << 2,
NotConfigurable = 1 << 3,
Writable = 1 << 4,
NotWritable = 1 << 5,
PreferNewLine = 1 << 6,
Default = Enumerable | Configurable | Writable | PreferNewLine,
DefaultDataProperty = Enumerable | Configurable | Writable | PreferNewLine,
DefaultAccessorProperty = Enumerable | Configurable | PreferNewLine,
EnumerableMask = Enumerable | NotEnumerable,
ConfigurableMask = Configurable | NotConfigurable,
WritableMask = Writable | NotWritable,
TrueMask = Enumerable | Configurable | Writable,
FalseMask = NotEnumerable | NotConfigurable | NotWritable,
DataPropertyMask = EnumerableMask | ConfigurableMask | WritableMask,
AccessorPropertyMask = EnumerableMask | ConfigurableMask,
}
export function createDataPropertyDescriptor(value: Expression, flags?: PropertyDescriptorFlags) {
return createPropertyDescriptor(/*get*/ undefined, /*set*/ undefined, value, flags);
}
export function createAccessorPropertyDescriptor(get: Expression, set: Expression, flags?: PropertyDescriptorFlags) {
return createPropertyDescriptor(get, set, /*value*/ undefined, flags);
}
function createPropertyDescriptor(get: Expression, set: Expression, value: Expression, flags: PropertyDescriptorFlags = PropertyDescriptorFlags.Default) {
let isDataProperty = get === undefined && set === undefined;
let properties: ObjectLiteralElement[] = [];
addPropertyDescriptorProperty(properties, isDataProperty, "get", flags, get);
addPropertyDescriptorProperty(properties, isDataProperty, "set", flags, set);
addPropertyDescriptorProperty(properties, isDataProperty, "value", flags, value);
addPropertyDescriptorOption(properties, isDataProperty, "enumerable", flags, PropertyDescriptorFlags.EnumerableMask);
addPropertyDescriptorOption(properties, isDataProperty, "configurable", flags, PropertyDescriptorFlags.ConfigurableMask);
addPropertyDescriptorOption(properties, isDataProperty, "writable", flags, PropertyDescriptorFlags.WritableMask);
return createObjectLiteralExpression(properties);
}
function addPropertyDescriptorProperty(properties: ObjectLiteralElement[], isDataProperty: boolean, propertyName: string, flags: PropertyDescriptorFlags, propertyValue: Expression) {
if (propertyValue && isDataProperty === (propertyName === "value")) {
let property = createPropertyAssignment2(propertyName, propertyValue);
startOnNewLine(property, (flags & PropertyDescriptorFlags.PreferNewLine) !== 0);
properties.push(property);
}
}
function addPropertyDescriptorOption(properties: ObjectLiteralElement[], isDataProperty: boolean, optionName: string, flags: PropertyDescriptorFlags, optionMask: PropertyDescriptorFlags) {
let flagsMask = isDataProperty
? PropertyDescriptorFlags.DataPropertyMask
: PropertyDescriptorFlags.AccessorPropertyMask;
if (flags & flagsMask & optionMask) {
let propertyValue = flags & PropertyDescriptorFlags.FalseMask
? createFalseKeyword()
: createTrueKeyword();
let property = createPropertyAssignment2(optionName, propertyValue);
startOnNewLine(property, (flags & PropertyDescriptorFlags.PreferNewLine) !== 0);
properties.push(property);
}
}
export function createDefinePropertyCall(target: Expression, memberName: Expression, descriptor: Expression, location?: TextRange) {
return createCallExpression2(createPropertyAccessExpression3(createIdentifier("Object"), "defineProperty"), [target, memberName, descriptor], location);
}
export function createDefinePropertyCall2(target: Expression, memberName: Expression, getter: Expression, setter: Expression, location?: TextRange) {
let properties: ObjectLiteralElement[] = [];
if (getter) {
let get = createPropertyAssignment2("get", getter);
properties.push(get);
startOnNewLine(get);
}
if (setter) {
let set = createPropertyAssignment2("set", setter)
startOnNewLine(set);
properties.push(set);
}
let enumerable = createPropertyAssignment2("enumerable", createTrueKeyword());
startOnNewLine(enumerable);
properties.push(enumerable);
let configurable = createPropertyAssignment2("configurable", createTrueKeyword());
startOnNewLine(configurable);
properties.push(configurable);
let descriptor = createObjectLiteralExpression(properties);
let descriptor = createAccessorPropertyDescriptor(getter, setter, PropertyDescriptorFlags.DefaultAccessorProperty);
return createDefinePropertyCall(target, memberName, descriptor, location);
}
@ -504,6 +590,10 @@ namespace ts {
: createElementAccessExpression2(target, cloneNode(memberName), location, flags);
}
export function createStringLiteralForIdentifier(name: Identifier): StringLiteral {
return createStringLiteral(name.text)
}
export function createExpressionForPropertyName(memberName: PropertyName, location?: TextRange): Expression {
return isIdentifier(memberName) ? createStringLiteral(memberName.text, location)
: isComputedPropertyName(memberName) ? cloneNode(memberName.expression, location)
@ -536,4 +626,16 @@ namespace ts {
}
return false;
}
function createIsObjectExpression(expression: LeftHandSideExpression) {
return createStrictEqualityExpression(createTypeOfExpression(expression), createStringLiteral("object"));
}
function createIsFunctionExpression(expression: LeftHandSideExpression) {
return createStrictEqualityExpression(createTypeOfExpression(expression), createStringLiteral("function"));
}
function createIsNotUndefinedExpression(expression: LeftHandSideExpression) {
return createStrictInequalityExpression(expression, createVoidZeroExpression());
}
}

View File

@ -396,6 +396,25 @@ namespace ts {
return result;
}
// @internal
export function parseSynthesizedStatements(sourceText: string) {
let sourceFile = Parser.parseSourceFile("parseStatement.ts", sourceText, ScriptTarget.Latest, /*syntaxCursor*/ undefined, /*setParentNodes*/ false, /*synthesized*/ true);
return sourceFile.statements;
}
// @internal
export function parseSynthesizedStatement(sourceText: string) {
let statements = parseSynthesizedStatements(sourceText);
return firstOrUndefined(statements);
}
// @internal
export function parseSynthesizedExpression(sourceText: string) {
let statement = parseSynthesizedStatement(`(${sourceText})`);
let expression = (<ExpressionStatement>statement).expression;
return (<ParenthesizedExpression>expression).expression;
}
// Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
// indicates what changed between the 'text' that this SourceFile has and the 'newText'.
// The SourceFile will be created with the compiler attempting to reuse as many nodes from
@ -518,10 +537,10 @@ namespace ts {
// attached to the EOF token.
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile {
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, synthesized?: boolean): SourceFile {
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes);
let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, synthesized);
clearState();
@ -561,7 +580,7 @@ namespace ts {
sourceText = undefined;
}
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile {
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, synthesized: boolean): SourceFile {
sourceFile = createSourceFile(fileName, languageVersion);
// Prime the scanner.
@ -583,6 +602,10 @@ namespace ts {
fixupParentReferences(sourceFile);
}
if (synthesized) {
makeSynthesized(sourceFile);
}
// If this is a javascript file, proactively see if we can get JSDoc comments for
// relevant nodes in the file. We'll use these to provide typing informaion if they're
// available.
@ -623,6 +646,22 @@ namespace ts {
}
}
function makeSynthesized(sourceFile: Node) {
visitNode(sourceFile);
function visitNode(n: Node) {
delete n.pos;
delete n.end;
forEachChild(n, visitNode, visitNodes);
}
function visitNodes(n: NodeArray<Node>) {
delete n.pos;
delete n.end;
forEach(n, visitNode);
}
}
export function fixupParentReferences(sourceFile: Node) {
// normally parent references are set during binding. However, for clients that only need
// a syntax tree, and no semantic features, then the binding process is an unnecessary
@ -3197,7 +3236,7 @@ namespace ts {
/**
* Parse ES7 unary expression and await expression
*
*
* ES7 UnaryExpression:
* 1) SimpleUnaryExpression[?yield]
* 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
@ -4973,8 +5012,8 @@ namespace ts {
// implements is a future reserved word so
// 'class implements' might mean either
// - class expression with omitted name, 'implements' starts heritage clause
// - class with name 'implements'
// 'isImplementsClause' helps to disambiguate between these two cases
// - class with name 'implements'
// 'isImplementsClause' helps to disambiguate between these two cases
return isIdentifier() && !isImplementsClause()
? parseIdentifier()
: undefined;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
/// <reference path="checker.ts" />
/// <reference path="transforms/jsx.ts" />
/// <reference path="transforms/ts.ts" />
/// <reference path="transforms/module/module.ts" />
/// <reference path="transforms/module/system.ts" />
/// <reference path="transforms/module/es6.ts" />
/// <reference path="transforms/jsx.ts" />
/// <reference path="transforms/es6.ts" />
const FORCE_TRANSFORMS = false;
@ -8,6 +11,16 @@ const FORCE_TRANSFORMS = false;
namespace ts {
export let transformTime = 0;
const moduleTransformationPhaseMap: Map<TransformationPhase> = {
[ModuleKind.ES2015]: createES6ModuleTransformation,
[ModuleKind.ES6]: createES6ModuleTransformation,
[ModuleKind.System]: createSystemModuleTransformation,
[ModuleKind.AMD]: createModuleTransformation,
[ModuleKind.CommonJS]: createModuleTransformation,
[ModuleKind.UMD]: createModuleTransformation,
[ModuleKind.None]: createModuleTransformation,
};
/**
* Represents a phase in a transformation chain. Used to initialize the transformation and
* return the transformation for the phase.
@ -21,23 +34,20 @@ namespace ts {
*/
export type TransformationChain = (transformer: Transformer) => Transformation;
/**
* Represents a transformation.
*/
export type Transformation = (node: SourceFile) => SourceFile;
/**
* Gets the default transformation chain for the provided set of compiler options.
*/
export function getTransformationChain(options: CompilerOptions): TransformationChain {
let jsx = options.jsx;
let languageVersion = options.target || ScriptTarget.ES3;
let moduleKind = options.module || ModuleKind.None;
export function getTransformationChain(compilerOptions: CompilerOptions): TransformationChain {
let jsx = compilerOptions.jsx;
let languageVersion = getLanguageVersion(compilerOptions);
let moduleKind = getModuleKind(compilerOptions);
let phases: TransformationPhase[] = [];
// Add the TypeScript and Module phases to the chain.
phases.push(createTypeScriptTransformation);
// // transforms.push(transformModule);
// Add the module transformation to the chain.
phases.push(moduleTransformationPhaseMap[moduleKind]);
// Add the JSX transform to the chain.
if (jsx === JsxEmit.React) {
@ -77,57 +87,6 @@ namespace ts {
LexicalEnvironmentEnded = 1 << 5,
}
// emit output for the __extends helper function
const extendsHelper = `
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};`;
// emit output for the __decorate helper function
const decorateHelper = `
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc);
switch (arguments.length) {
case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
}
};`;
// emit output for the __metadata helper function
const metadataHelper = `
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};`;
// emit output for the __param helper function
const paramHelper = `
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};`;
const awaiterHelper = `
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
return new Promise(function (resolve, reject) {
generator = generator.apply(thisArg, _arguments);
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
function step(verb, value) {
var result = generator[verb](value);
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
}
step("next", void 0);
});
};`;
const exportStarHelper = `
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}`;
let compilerOptions = host.getCompilerOptions();
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
let transformFlags: TransformFlags;
@ -150,9 +109,8 @@ function __export(m) {
let updatedNode: Node;
let updatedNodes: Node[];
let helpersEmitted: NodeCheckFlags;
let assignmentSubstitution: (node: BinaryExpression) => Expression;
let bindingIdentifierSubstitution: (node: Identifier) => Identifier;
let expressionIdentifierSubstitution: (node: Identifier) => LeftHandSideExpression;
let expressionSubstitution: (node: Expression) => Expression;
let generatedNodeFlags: GeneratedNodeFlags[] = [];
let transformer: Transformer = {
getEmitResolver: () => resolver,
getCompilerOptions: () => compilerOptions,
@ -163,6 +121,7 @@ function __export(m) {
tryPushNode: node => nodeStack.tryPushNode(node),
pushNode: node => nodeStack.pushNode(node),
popNode: () => nodeStack.popNode(),
setNode: node => nodeStack.setNode(node),
findAncestorNode: (match: (node: Node) => boolean) => nodeStack.findAncestorNode(match),
getDeclarationName,
getClassMemberPrefix,
@ -174,16 +133,13 @@ function __export(m) {
declareLocal,
hoistVariableDeclaration,
hoistFunctionDeclaration,
emitEmitHelpers,
emitExportStarHelper,
getAssignmentSubstitution,
setAssignmentSubstitution,
getBindingIdentifierSubstitution,
setBindingIdentifierSubstitution,
getExpressionIdentifierSubstitution,
setExpressionIdentifierSubstitution,
getGeneratedNodeFlags,
setGeneratedNodeFlags,
getExpressionSubstitution,
setExpressionSubstitution,
startLexicalEnvironment,
endLexicalEnvironment,
createNodes,
pipeNode,
pipeNodes,
mapNode,
@ -197,7 +153,12 @@ function __export(m) {
visitFunctionBody,
visitConciseBody,
accept(node: Node, visitor: (node: Node, write: (node: Node) => void) => void) {
return acceptTransformer(transformer, node, visitor);
let wasPushed = node && nodeStack.tryPushNode(node);
node = acceptTransformer(transformer, node, visitor);
if (wasPushed) {
nodeStack.popNode();
}
return node;
}
};
@ -206,12 +167,30 @@ function __export(m) {
return {
sourceFiles: map(sourceFiles, transformSourceFile),
substitutions: {
assignmentSubstitution,
bindingIdentifierSubstitution,
expressionIdentifierSubstitution,
getGeneratedNodeFlags,
expressionSubstitution,
}
};
function getGeneratedNodeFlags(node: Node) {
let lastNode: Node;
while (node) {
let nodeId = getNodeId(node);
if (nodeId in generatedNodeFlags) {
return generatedNodeFlags[nodeId];
}
lastNode = node;
node = node.original;
}
return undefined;
}
function setGeneratedNodeFlags(node: Node, flags: GeneratedNodeFlags) {
generatedNodeFlags[getNodeId(node)] = flags;
}
function transformSourceFile(sourceFile: SourceFile) {
if (isDeclarationFile(sourceFile)) {
return sourceFile;
@ -240,28 +219,12 @@ function __export(m) {
return visited;
}
function getAssignmentSubstitution(): (node: BinaryExpression) => Expression {
return assignmentSubstitution;
function getExpressionSubstitution(): (node: Expression) => Expression {
return expressionSubstitution;
}
function setAssignmentSubstitution(substitution: (node: BinaryExpression) => Expression) {
assignmentSubstitution = substitution;
}
function getBindingIdentifierSubstitution(): (node: Identifier) => Identifier {
return bindingIdentifierSubstitution;
}
function setBindingIdentifierSubstitution(substitution: (node: Identifier) => Identifier): void {
bindingIdentifierSubstitution = substitution;
}
function getExpressionIdentifierSubstitution(): (node: Identifier) => LeftHandSideExpression {
return expressionIdentifierSubstitution;
}
function setExpressionIdentifierSubstitution(substitution: (node: Identifier) => LeftHandSideExpression) {
expressionIdentifierSubstitution = substitution;
function setExpressionSubstitution(substitution: (node: Expression) => Expression) {
expressionSubstitution = substitution;
}
// Return the next available name in the pattern _a ... _z, _0, _1, ...
@ -467,43 +430,6 @@ function __export(m) {
hoistedFunctionDeclarations.push(func);
}
function emitEmitHelpers(write: (node: Statement) => void) {
if (compilerOptions.noEmitHelpers) {
return;
}
if (languageVersion < ScriptTarget.ES6 && shouldEmitHelper(NodeCheckFlags.EmitExtends)) {
write(createRawStatement(extendsHelper));
helpersEmitted |= NodeCheckFlags.EmitExtends;
}
if (shouldEmitHelper(NodeCheckFlags.EmitDecorate)) {
write(createRawStatement(decorateHelper));
helpersEmitted |= NodeCheckFlags.EmitDecorate;
}
if (shouldEmitHelper(NodeCheckFlags.EmitParam)) {
write(createRawStatement(paramHelper));
helpersEmitted |= NodeCheckFlags.EmitParam;
}
if (shouldEmitHelper(NodeCheckFlags.EmitAwaiter)) {
write(createRawStatement(awaiterHelper));
helpersEmitted |= NodeCheckFlags.EmitAwaiter;
}
}
function emitExportStarHelper(write: (node: Statement) => void) {
if (shouldEmitHelper(NodeCheckFlags.EmitExportStar)) {
write(createRawStatement(exportStarHelper));
}
}
function shouldEmitHelper(flags: NodeCheckFlags) {
return !(helpersEmitted & flags)
&& !!(resolver.getNodeCheckFlags(currentSourceFile) & flags);
}
function aggregateTransformFlags(node: Node) {
if (!node) {
return;
@ -656,7 +582,6 @@ function __export(m) {
}
function readNode(): Node {
Debug.assert(!!updatedNode, "Not enough nodes written to output.");
return updatedNode;
}
@ -672,6 +597,53 @@ function __export(m) {
}
}
function createNodes<TOut extends Node>(callback: (write: (node: TOut) => void) => void, out?: ((node: TOut) => void) | TOut[]): NodeArray<TOut> {
let write: (node: Node) => void;
let readNodes: () => NodeArray<Node>;
let outputArray: TOut[];
if (typeof out === "function") {
write = out as (node: Node) => void;
}
else {
write = writeNodeToNodeArray;
readNodes = readNodeArray;
outputArray = out as TOut[] || [];
}
// Preserve the previous environment on the call stack.
let savedOriginalNodes = originalNodes;
let savedWriteOffset = writeOffset;
let savedUpdatedNode = updatedNode;
let savedUpdatedNodes = updatedNodes;
let savedNodeTest = nodeTest;
let savedCurrentVisitFlags = currentVisitFlags;
// Set the new environment.
originalNodes = undefined;
writeOffset = undefined;
updatedNode = undefined;
updatedNodes = outputArray;
nodeTest = undefined;
currentVisitFlags = undefined;
requestedVisitFlags = undefined;
// Execute the callback
callback(write);
// Read the result
let resultNodes = readNodes ? readNodes() : undefined;
// Restore the previous environment.
originalNodes = savedOriginalNodes;
writeOffset = savedWriteOffset;
updatedNode = savedUpdatedNode;
updatedNodes = savedUpdatedNodes;
nodeTest = savedNodeTest;
currentVisitFlags = savedCurrentVisitFlags;
return resultNodes as NodeArray<TOut>;
}
function visitNodeOrNodes(node: Node, nodes: Node[], start: number, count: number, visitor: (node: Node, write: (node: Node) => void) => void,
write: (node: Node) => void, readNode?: () => Node, readNodes?: () => NodeArray<Node>, out?: Node[], test?: (node: Node) => boolean): Node | NodeArray<Node> {
let resultNode: Node;

View File

@ -0,0 +1,278 @@
/// <reference path="../checker.ts" />
/*@internal*/
namespace ts {
/**
* Flattens binding patterns in a variable declaration.
* @param transformer The transformer context to use during destructuring.
* @param node The variable declaration to flatten.
* @param write The callback to execute to write variable declarations.
* @param visitor An optional visitor used to visit the initializers of a binding pattern.
*/
export function flattenVariableDestructuring(transformer: Transformer, node: VariableDeclaration, write: (node: VariableDeclaration) => void, visitor?: (node: Node, write: (node: Node) => void) => void): void {
transformDestructuring(transformer, node, /*writeExpression*/ undefined, write, visitor, node.initializer);
}
/**
* Flattens binding patterns in a parameter declaration.
* @param transformer The transformer context to use during destructuring.
* @param node The parameter declaration to flatten.
* @param write The callback to execute to write variable declarations.
* @param visitor An optional visitor used to visit the initializers of a binding pattern.
*/
export function flattenParameterDestructuring(transformer: Transformer, node: ParameterDeclaration, write: (node: VariableDeclaration) => void, visitor?: (node: Node, write: (node: Node) => void) => void): void {
transformDestructuring(transformer, node, /*writeExpression*/ undefined, write, visitor, transformer.getGeneratedNameForNode(node));
}
/**
* Flattens a destructuring assignment.
* @param transformer The transformer context to use during destructuring.
* @param node The assignment expression to flatten.
* @param write The callback to execute to write the resulting expression.
* @param visitor An optional visitor used to visit the initializers and right-hand side of the destructuring assignment.
*/
export function flattenDestructuringAssignment(transformer: Transformer, node: BinaryExpression, write: (node: Expression) => void, visitor?: (node: Node, write: (node: Node) => void) => void): void {
transformDestructuring(transformer, node, write, /*writeDeclaration*/ undefined, visitor);
}
/**
* Flattens binding patterns in a variable declaration and transforms them into an expression.
* @param transformer The transformer context to use during destructuring.
* @param node The variable declaration to flatten.
* @param write The callback to execute to write the resulting expression.
* @param visitor An optional visitor used to visit the initializers of a binding pattern.
*/
export function flattenVariableDestructuringAsExpression(transformer: Transformer, node: VariableDeclaration, write: (node: Expression) => void, visitor?: (node: Node, write: (node: Node) => void) => void): void {
transformDestructuring(transformer, node, write, /*writeDeclaration*/ undefined, visitor);
}
function transformDestructuring(
transformer: Transformer,
root: BinaryExpression | VariableDeclaration | ParameterDeclaration,
writeExpression: (node: Expression) => void,
writeDeclaration: (node: VariableDeclaration) => void,
visitor?: (node: Node, write: (node: Node) => void) => void,
value?: Expression) {
let {
createTempVariable,
hoistVariableDeclaration,
mapNode,
flattenNode,
visitNode,
} = transformer;
let parentNode = transformer.getParentNode();
let isVariableDeclarationList = writeDeclaration !== undefined;
if (isBinaryExpression(root)) {
return emitAssignmentExpression(root, writeExpression);
}
else {
return emitBindingElement(<BindingElement>root, value, writeExpression || writeDeclaration);
}
function emitAssignmentExpression(root: BinaryExpression, write: (node: Expression) => void) {
if (isEmptyObjectLiteralOrArrayLiteral(root.left)) {
return write(root.right);
}
else {
let expressions = flattenNode(root, emitDestructuringExpressions);
let expression = inlineExpressions(expressions);
if (!isExpressionStatement(parentNode) && !isParenthesizedExpression(parentNode)) {
expression = createParenthesizedExpression(expression);
}
return write(expression);
}
}
function emitBindingElement(target: BindingElement, value: Expression, write: (node: Expression | VariableDeclaration) => void): void {
if (target.initializer) {
// Combine value and initializer
let initializer = visitNode(target.initializer, visitor, isExpressionNode);
value = value ? createDefaultValueCheck(value, initializer, write) : initializer;
}
else if (!value) {
// Use 'void 0' in absence of value and initializer
value = createVoidZeroExpression();
}
let 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, write);
}
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
if (name.kind === SyntaxKind.ObjectBindingPattern) {
// Rewrite element to a declaration with an initializer that fetches property
let propName = element.propertyName || <Identifier>element.name;
emitBindingElement(element, createPropertyOrElementAccessExpression(value, propName), write);
}
else if (element.kind !== SyntaxKind.OmittedExpression) {
if (!element.dotDotDotToken) {
// Rewrite element to a declaration that accesses array element at index i
emitBindingElement(element, createElementAccessExpression3(value, i), write);
}
else if (i === elements.length - 1) {
emitBindingElement(element, createSliceCall(value, i), write);
}
}
}
}
else {
emitAssignment(name, value, /*isTempVariable*/ false, write);
}
}
function emitDestructuringExpressions(node: BinaryExpression, write: (node: Expression) => void): void {
let target = node.left;
let value = node.right;
if (isExpressionStatement(parentNode)) {
emitDestructuringAssignment(target, value, write);
}
else {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, write);
emitDestructuringAssignment(target, value, write);
write(value);
}
}
function emitDestructuringAssignment(target: Expression, value: Expression, write: (node: Expression) => void) {
if (isBinaryExpression(target) && target.operatorToken.kind === SyntaxKind.EqualsToken) {
let right = visitNode((<BinaryExpression>target).right, visitor, isExpressionNode);
value = createDefaultValueCheck(value, right, write);
target = (<BinaryExpression>target).left;
}
if (isObjectLiteralExpression(target)) {
emitObjectLiteralAssignment(target, value, write);
}
else if (isArrayLiteralExpression(target)) {
emitArrayLiteralAssignment(target, value, write);
}
else if (isIdentifier(target)) {
emitAssignment(target, value, /*isTempVariable*/ false, write);
}
else {
Debug.fail();
}
}
function emitObjectLiteralAssignment(target: ObjectLiteralExpression, value: Expression, write: (node: Expression) => void): void {
let 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.
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, write);
}
for (let p of properties) {
if (isPropertyAssignment(p) || isShorthandPropertyAssignment(p)) {
let propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
let expr = createPropertyOrElementAccessExpression(value, propName);
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, expr, write);
}
}
}
function emitArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, write: (node: Expression) => void): void {
let elements = target.elements;
if (elements.length !== 1) {
// For anything but a single element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once.
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, write);
}
for (let i = 0; i < elements.length; i++) {
let e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
if (e.kind !== SyntaxKind.SpreadElementExpression) {
emitDestructuringAssignment(e, createElementAccessExpression3(value, i), write);
}
else if (i === elements.length - 1) {
emitDestructuringAssignment((<SpreadElementExpression>e).expression, createSliceCall(value, i), write);
}
}
}
}
function emitAssignment(left: Identifier, right: Expression, isTempVariable: boolean, write: (node: Expression | VariableDeclaration) => void): void {
if (isVariableDeclarationList) {
write(createVariableDeclaration2(left, right));
}
else {
write(createAssignmentExpression(left, right));
}
}
function ensureIdentifier(value: Expression, reuseIdentifierExpressions: boolean, write: (node: Expression | VariableDeclaration) => void) {
if (isIdentifier(value) && reuseIdentifierExpressions) {
return value;
}
else {
let temp = createTempVariable(TempFlags.Auto);
if (!isVariableDeclarationList) {
hoistVariableDeclaration(temp);
}
emitAssignment(temp, value, /*isTempVariable*/ true, write);
return temp;
}
}
function createDefaultValueCheck(value: Expression, defaultValue: Expression, write: (node: Expression | VariableDeclaration) => void): Expression {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, write);
let equalityExpr = createStrictEqualityExpression(value, createVoidZeroExpression());
return createConditionalExpression2(equalityExpr, defaultValue, value);
}
}
export function convertBindingPatternToExpression(node: BindingPattern): Expression {
switch (node.kind) {
case SyntaxKind.ObjectBindingPattern:
return convertObjectBindingPatternToExpression(<ObjectBindingPattern>node);
case SyntaxKind.ArrayBindingPattern:
return convertArrayBindingPatternToExpression(<ObjectBindingPattern>node);
}
}
function convertBindingElementToExpression(node: BindingElement): Expression {
let name = node.name;
let expression = isIdentifier(name) ? name : convertBindingPatternToExpression(name);
if (node.initializer) {
expression = createAssignmentExpression(expression, node.initializer, node);
}
else if (node.dotDotDotToken) {
expression = createSpreadElementExpression(expression, node);
}
return expression;
}
function convertObjectBindingPatternToExpression(node: ObjectBindingPattern): Expression {
let properties = map(node.elements, convertBindingElementToObjectLiteralElement);
return createObjectLiteralExpression(properties);
}
function convertArrayBindingPatternToExpression(node: ArrayBindingPattern): Expression {
let elements = map(node.elements, convertBindingElementToExpression);
return createArrayLiteralExpression(elements);
}
function convertBindingElementToObjectLiteralElement(node: BindingElement): ObjectLiteralElement {
let name = node.name;
if (!node.propertyName && isIdentifier(name) && !node.initializer) {
return createShorthandPropertyAssignment(name, node);
}
let propertyName = node.propertyName || <Identifier>name;
let expr = convertBindingElementToExpression(node);
return createPropertyAssignment(propertyName, expr);
}
}

View File

@ -1,4 +1,5 @@
/// <reference path="../checker.ts" />
/// <refernece path="./destructuring.ts" />
/*@internal*/
namespace ts {
export function createES6Transformation(transformer: Transformer): Transformation {
@ -329,83 +330,7 @@ namespace ts {
}
function emitParameterBindingElements(parameter: ParameterDeclaration, write: (node: VariableDeclaration) => void): void {
let tempName = getGeneratedNameForNode(parameter);
emitBindingElement(parameter, tempName, write);
}
function emitBindingElement(target: BindingElement, value: Expression, write: (node: VariableDeclaration) => void): void {
if (target.initializer) {
// Combine value and initializer
let initializer = visitNode(target.initializer, visitor, isExpressionNode);
value = value ? createDefaultValueCheck(value, initializer, /*isVariableDeclarationList*/ true, write) : initializer;
}
else if (!value) {
// Use 'void 0' in absence of value and initializer
value = createVoidZeroExpression();
}
let 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, /*isVariableDeclarationList*/ true, write);
}
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
if (name.kind === SyntaxKind.ObjectBindingPattern) {
// Rewrite element to a declaration with an initializer that fetches property
let propName = element.propertyName || <Identifier>element.name;
emitBindingElement(element, createPropertyOrElementAccessExpression(value, propName), write);
}
else if (element.kind !== SyntaxKind.OmittedExpression) {
if (!element.dotDotDotToken) {
// Rewrite element to a declaration that accesses array element at index i
emitBindingElement(element, createElementAccessExpression3(value, i), write);
}
else if (i === elements.length - 1) {
emitBindingElement(element, createSliceCall(value, i), write);
}
}
}
}
else {
emitAssignment(name, value, /*isTempVariable*/ false, /*isVariableDeclarationList*/ true, write);
}
}
function emitAssignment(left: Identifier, right: Expression, isTempVariable: boolean, isVariableDeclarationList: boolean, write: (node: Expression | VariableDeclaration) => void): void {
if (isVariableDeclarationList) {
write(createVariableDeclaration2(left, right));
}
else {
write(createAssignmentExpression(left, right));
}
}
function ensureIdentifier(value: Expression, reuseIdentifierExpressions: boolean, isVariableDeclarationList: boolean, write: (node: Expression | VariableDeclaration) => void) {
if (isIdentifier(value) && reuseIdentifierExpressions) {
return value;
}
else {
let temp = createTempVariable(TempFlags.Auto);
if (!isVariableDeclarationList) {
hoistVariableDeclaration(temp);
}
emitAssignment(temp, value, /*isTempVariable*/ true, isVariableDeclarationList, write);
return temp;
}
}
function createDefaultValueCheck(value: Expression, defaultValue: Expression, isVariableDeclarationList: boolean, write: (node: Expression | VariableDeclaration) => void): Expression {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, isVariableDeclarationList, write);
let equalityExpr = createStrictEqualityExpression(value, createVoidZeroExpression());
return createConditionalExpression2(equalityExpr, defaultValue, value);
flattenParameterDestructuring(transformer, parameter, write, visitor);
}
function emitDefaultValueAssignmentForInitializer(parameter: ParameterDeclaration, name: Identifier, initializer: Expression, write: (node: Statement) => void): void {
@ -421,7 +346,7 @@ namespace ts {
}
function shouldEmitRestParameter(node: ParameterDeclaration) {
return node.dotDotDotToken && !(node.flags & NodeFlags.GeneratedRest);
return node.dotDotDotToken && !(node.flags & NodeFlags.Generated);
}
function emitRestParameter(node: FunctionLikeDeclaration, write: (node: Statement) => void): void {
@ -560,89 +485,7 @@ namespace ts {
function visitBinaryExpression(node: BinaryExpression, write: (node: Expression) => void): void {
// If we are here it is because this is a destructuring assignment.
if (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
write(node.right);
}
else {
let expressions = flattenNode(node, emitDestructuringExpressions);
let expression = inlineExpressions(expressions);
let parentNode = getParentNode();
if (!isExpressionStatement(parentNode) && !isParenthesizedExpression(parentNode)) {
expression = createParenthesizedExpression(expression);
}
write(expression);
}
}
function emitDestructuringExpressions(node: BinaryExpression, write: (node: Expression) => void): void {
let target = node.left;
let value = node.right;
let parentNode = getParentNode();
if (isExpressionStatement(parentNode)) {
emitDestructuringAssignment(target, value, write);
}
else {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, /*isVariableDeclarationList*/ false, write);
emitDestructuringAssignment(target, value, write);
write(value);
}
}
function emitDestructuringAssignment(target: Expression, value: Expression, write: (node: Expression) => void) {
if (isBinaryExpression(target) && target.operatorToken.kind === SyntaxKind.EqualsToken) {
value = createDefaultValueCheck(value, (<BinaryExpression>target).right, /*isVariableDeclarationList*/ false, write);
target = (<BinaryExpression>target).left;
}
if (isObjectLiteralExpression(target)) {
emitObjectLiteralAssignment(target, value, write);
}
else if (isArrayLiteralExpression(target)) {
emitArrayLiteralAssignment(target, value, write);
}
else if (isIdentifier(target)) {
emitAssignment(target, value, /*isTempVariable*/ false, /*isVariableDeclarationList*/ false, write);
}
else {
Debug.fail();
}
}
function emitObjectLiteralAssignment(target: ObjectLiteralExpression, value: Expression, write: (node: Expression) => void): void {
let 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.
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, /*isVariableDeclarationList*/ false, write);
}
for (let p of properties) {
if (isPropertyAssignment(p) || isShorthandPropertyAssignment(p)) {
let propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
let expr = createPropertyOrElementAccessExpression(value, propName);
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, expr, write);
}
}
}
function emitArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, write: (node: Expression) => void): void {
let elements = target.elements;
if (elements.length !== 1) {
// For anything but a single element destructuring we need to generate a temporary
// to ensure value is evaluated exactly once.
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, /*isVariableDeclarationList*/ false, write);
}
for (let i = 0; i < elements.length; i++) {
let e = elements[i];
if (e.kind !== SyntaxKind.OmittedExpression) {
if (e.kind !== SyntaxKind.SpreadElementExpression) {
emitDestructuringAssignment(e, createElementAccessExpression3(value, i), write);
}
else if (i === elements.length - 1) {
emitDestructuringAssignment((<SpreadElementExpression>e).expression, createSliceCall(value, i), write);
}
}
}
flattenDestructuringAssignment(transformer, node, write, visitor);
}
function visitVariableStatement(node: VariableStatement, write: (node: Statement) => void): void {
@ -658,7 +501,7 @@ namespace ts {
function visitVariableDeclaration(node: VariableDeclaration, write: (node: VariableDeclaration) => void): void {
if (isBindingPattern(node.name)) {
emitBindingElement(node, node.initializer, write);
flattenVariableDestructuring(transformer, node, write, visitor);
}
else {
// TODO(rbuckton): Is there any reason we should hit this branch?
@ -1138,7 +981,7 @@ namespace ts {
}
function visitExpressionStatement(node: ExpressionStatement, write: (node: Statement) => void): void {
if (node.flags & NodeFlags.GeneratedSuper) {
if (node.flags & NodeFlags.Generated) {
write(createDefaultSuperCall());
}
else {

View File

@ -0,0 +1,11 @@
/// <reference path="./module.ts" />
/*@internal*/
namespace ts {
export function createES6ModuleTransformation(transformer: Transformer): Transformation {
return transformES6Module;
function transformES6Module(node: SourceFile) {
return node;
}
}
}

View File

@ -0,0 +1,706 @@
/// <reference path="../../checker.ts" />
/*@internal*/
namespace ts {
export function createModuleTransformation(transformer: Transformer): Transformation {
const emitModuleDelegates: Map<(node: SourceFile, write: (node: Statement) => void) => void> = {
[ModuleKind.None]: emitCommonJSModule,
[ModuleKind.AMD]: emitAMDModule,
[ModuleKind.UMD]: emitUMDModule,
[ModuleKind.CommonJS]: emitCommonJSModule,
};
let {
makeUniqueName,
getGeneratedNameForNode,
hoistVariableDeclaration,
hoistFunctionDeclaration,
startLexicalEnvironment,
endLexicalEnvironment,
pipeNode,
pipeNodes,
mapNode,
mapNodes,
flattenNode,
visitNode,
visitNodes,
accept
} = transformer;
let compilerOptions = transformer.getCompilerOptions();
let resolver = transformer.getEmitResolver();
let languageVersion = getLanguageVersion(compilerOptions);
let moduleKind = getModuleKind(compilerOptions);
let currentSourceFile: SourceFile;
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
let exportSpecifiers: Map<ExportSpecifier[]>;
let exportEquals: ExportAssignment;
let hasExportStars: boolean;
let exportAssignmentWriter: (node: Statement) => void;
let savedExpressionSubstution = transformer.getExpressionSubstitution();
transformer.setExpressionSubstitution(substituteExpressionWithFallback);
return transformModule;
/**
* Transforms a source file via the provided module emit callback.
*/
function transformModule(node: SourceFile): SourceFile {
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
// collect information about the external module
({ externalImports, exportSpecifiers, exportEquals, hasExportStars } = collectExternalModuleInfo(node, resolver));
let emitModule = emitModuleDelegates[moduleKind];
node = updateSourceFileNode(node, flattenNode(node, emitModule), node.endOfFileToken);
if (hasExportStars && emitModule === emitCommonJSModule) {
transformer.setGeneratedNodeFlags(node, GeneratedNodeFlags.EmitExportStar);
}
currentSourceFile = undefined;
}
return node;
}
/**
* Emits file prologue directives prior to a module body.
*/
function emitPrologueDirectives(statements: NodeArray<Statement>, write: (node: Statement) => void): number {
for (let i = 0; i < statements.length; ++i) {
if (isPrologueDirective(statements[i])) {
write(statements[i]);
}
else {
return i;
}
}
return statements.length;
}
/**
* Emits a CommonJS module.
*/
function emitCommonJSModule(node: SourceFile, write: (node: Statement) => void) {
startLexicalEnvironment();
let statementOffset = emitPrologueDirectives(node.statements, write);
pipeNodes(node.statements, visitModuleElement, write, statementOffset);
endLexicalEnvironment(write);
let exportEquals = tryCreateExportEquals(/*emitAsReturn*/ false);
if (exportEquals) {
write(exportEquals);
}
}
/**
* Emits an AMD module.
*/
function emitAMDModule(node: SourceFile, write: (node: Statement) => void) {
let define = createIdentifier("define");
let moduleName = node.moduleName ? createStringLiteral(node.moduleName) : undefined;
emitAsynchronousModule(node, write, define, moduleName, /*includeNonAmdDependencies*/ true);
}
/**
* Emits an UMD module.
*/
function emitUMDModule(node: SourceFile, write: (node: Statement) => void) {
let define = createIdentifier("define");
transformer.setGeneratedNodeFlags(define, GeneratedNodeFlags.UMDDefine);
emitAsynchronousModule(node, write, define, /*moduleName*/ undefined, /*includeNonAmdDependencies*/ false);
}
/**
* Emits an asynchronous module (AMD/UMD).
* @param node The source file to transform.
* @param write The callback used to emit the module body.
* @param define The expression called to define the asynchronous module body.
* @param moduleName The expression
*/
function emitAsynchronousModule(node: SourceFile, write: (node: Statement) => void, define: Expression, moduleName: Expression, includeNonAmdDependencies: boolean) {
// Start the lexical environment for the source file.
startLexicalEnvironment();
let statementOffset = emitPrologueDirectives(node.statements, write);
// An AMD define function has the following shape:
// define(id?, dependencies?, factory);
//
// This has the shape of
// 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
let defineArguments: Expression[] = [];
if (moduleName) {
defineArguments.push(moduleName);
}
let aliasedModuleNames: Expression[] = [
createStringLiteral("require"),
createStringLiteral("exports")
];
let unaliasedModuleNames: Expression[] = [];
let importAliasNames: ParameterDeclaration[] = [
createParameter3("require"),
createParameter3("exports")
];
for (let amdDependency of node.amdDependencies) {
if (amdDependency.name) {
aliasedModuleNames.push(createStringLiteral(amdDependency.name));
importAliasNames.push(createParameter3(amdDependency.name));
}
else {
unaliasedModuleNames.push(createStringLiteral(amdDependency.path));
}
}
for (let importNode of externalImports) {
// Find the name of the external module
let externalModuleName = getExternalModuleNameLiteral(importNode);
// Find the name of the module alias, if there is one
let importAliasName = getLocalNameForExternalImport(importNode);
if (includeNonAmdDependencies && importAliasName) {
aliasedModuleNames.push(externalModuleName);
importAliasNames.push(createParameter2(importAliasName));
}
else {
unaliasedModuleNames.push(externalModuleName);
}
}
// Create the import names array.
let imports = createArrayLiteralExpression(concatenate(aliasedModuleNames, unaliasedModuleNames));
defineArguments.push(imports);
// Create the body of the module.
let statements: Statement[] = [];
// Start the lexical environment for the module body.
startLexicalEnvironment();
// Pipe each statement of the source file through a visitor and out to the module body
pipeNodes(node.statements, visitModuleElement, statements, statementOffset);
// End the lexical environment for the module body.
endLexicalEnvironment(statements);
// Append the 'export =' statement if provided.
let exportEquals = tryCreateExportEquals(/*emitAsReturn*/ true);
if (exportEquals) {
statements.push(exportEquals);
}
// Create the function for the module body.
let moduleBody = createBlock(statements);
if (hasExportStars) {
transformer.setGeneratedNodeFlags(moduleBody, GeneratedNodeFlags.EmitExportStar);
}
let moduleFunc = createFunctionExpression3(importAliasNames, moduleBody);
defineArguments.push(moduleFunc);
// create the definition
let defineCall = createCallExpression2(define, defineArguments);
write(createExpressionStatement(defineCall));
// End the lexical environment for the source file.
endLexicalEnvironment(write);
}
function visitModuleElement(node: Statement, write: (node: Statement) => void) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
return visitImportDeclaration(<ImportDeclaration>node, write);
case SyntaxKind.ImportEqualsDeclaration:
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node, write);
case SyntaxKind.ExportDeclaration:
return visitExportDeclaration(<ExportDeclaration>node, write);
case SyntaxKind.ExportAssignment:
return visitExportAssignment(<ExportAssignment>node, write);
case SyntaxKind.VariableStatement:
return visitVariableStatement(<VariableStatement>node, write);
case SyntaxKind.FunctionDeclaration:
return visitFunctionDeclaration(<FunctionDeclaration>node, write);
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(<ClassDeclaration>node, write);
default:
return write(node);
}
}
function visitImportDeclaration(node: ImportDeclaration, write: (node: Statement) => void): void {
if (contains(externalImports, node)) {
let namespaceDeclaration = getNamespaceDeclarationNode(node);
if (moduleKind !== ModuleKind.AMD) {
let require = createRequireCall(node);
if (!node.importClause) {
// import "mod";
write(createExpressionStatement(require, /*location*/ node));
}
else {
let variables: VariableDeclaration[] = [];
if (namespaceDeclaration && !isDefaultImport(node)) {
// import * as n from "mod";
variables.push(createVariableDeclaration2(makeSynthesized(namespaceDeclaration.name), require));
}
else {
// import d from "mod";
// import { x, y } from "mod";
// import d, { x, y } from "mod";
// import d, * as n from "mod";
variables.push(createVariableDeclaration2(getGeneratedNameForNode(node), require));
if (namespaceDeclaration && isDefaultImport(node)) {
variables.push(createVariableDeclaration2(makeSynthesized(namespaceDeclaration.name), getGeneratedNameForNode(node)));
}
}
write(createVariableStatement2(createVariableDeclarationList(variables), /*location*/ node));
}
}
else if (namespaceDeclaration && isDefaultImport(node)) {
// import d, * as n from "mod";
write(createVariableStatement3(makeSynthesized(namespaceDeclaration.name), getGeneratedNameForNode(node), /*location*/ node));
}
emitExportImportAssignments(node, write);
}
}
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration, write: (node: Statement) => void): void {
if (contains(externalImports, node)) {
if (moduleKind !== ModuleKind.AMD) {
let require = createRequireCall(node);
if (node.flags & NodeFlags.Export) {
write(createExpressionStatement(createExportAssignment(node.name, require), /*location*/ node));
}
else {
write(createVariableStatement3(makeSynthesized(node.name), require, /*location*/ node));
}
}
else {
if (node.flags & NodeFlags.Export) {
write(createExpressionStatement(createExportAssignment(node.name, node.name), /*location*/ node));
}
}
emitExportImportAssignments(node, write);
}
}
function visitExportDeclaration(node: ExportDeclaration, write: (node: Statement) => void): void {
if (contains(externalImports, node)) {
let generatedName = getGeneratedNameForNode(node);
if (node.exportClause) {
// export { x, y } from "mod";
if (moduleKind !== ModuleKind.AMD) {
write(createVariableStatement3(generatedName, createRequireCall(node)));
}
for (let specifier of node.exportClause.elements) {
if (resolver.isValueAliasDeclaration(specifier)) {
let exportedValue = createPropertyAccessExpression2(generatedName, specifier.propertyName || specifier.name);
write(createExpressionStatement(createExportAssignment(specifier.name, exportedValue), /*location*/ specifier));
}
}
}
else {
// export * from "mod";
if (moduleKind !== ModuleKind.AMD) {
write(createExpressionStatement(createExportStarHelperCall(createRequireCall(node)), /*location*/ node));
}
else {
write(createExpressionStatement(createExportStarHelperCall(generatedName), /*location*/ node));
}
}
}
}
function visitExportAssignment(node: ExportAssignment, write: (node: Statement) => void): void {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
emitExportDefault(node.expression, /*location*/ node, write);
}
}
function emitExportDefault(expression: Expression, location: TextRange, write: (node: Statement) => void): void {
emitExportDefaultCompat(write);
let defaultName = createIdentifier("default", SyntaxKind.DefaultKeyword);
write(createExpressionStatement(createExportAssignment(defaultName, expression), location));
}
function emitExportDefaultCompat(write: (node: Statement) => void): void {
let originalSourceFile = getOriginalNodeIf(currentSourceFile, isSourceFile);
if (!originalSourceFile.symbol.exports["___esModule"]) {
if (languageVersion === ScriptTarget.ES3) {
let esModule = createIdentifier("__esModule");
write(createExpressionStatement(createExportAssignment(esModule, createTrueKeyword())));
}
else {
let exports = createIdentifier("exports");
let esModule = createStringLiteral("__esModule");
let descriptor = createDataPropertyDescriptor(createTrueKeyword(), PropertyDescriptorFlags.Empty);
write(createExpressionStatement(createDefinePropertyCall(exports, esModule, descriptor)));
}
}
}
function emitExportImportAssignments(node: Node, write: (node: Statement) => void) {
let savedExportImportAssignmentWriter = exportAssignmentWriter;
exportAssignmentWriter = write;
emitExportImportAssignmentsUsingCapturedWriter(node);
exportAssignmentWriter = savedExportImportAssignmentWriter;
}
function emitExportImportAssignmentsUsingCapturedWriter(node: Node) {
if (isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node)) {
emitExportMemberAssignmentsUsingCapturedWriter(<Identifier>(<Declaration>node).name);
}
forEachChild(node, emitExportImportAssignmentsUsingCapturedWriter);
}
function emitExportMemberAssignmentsUsingCapturedWriter(name: Identifier) {
emitExportMemberAssignments(name, exportAssignmentWriter);
}
function emitExportMemberAssignments(name: Identifier, write: (node: Statement) => void): void {
if (!exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, name.text)) {
for (let specifier of exportSpecifiers[name.text]) {
write(createExpressionStatement(createExportAssignment(specifier.name, name), /*location*/ specifier.name));
}
}
}
function visitVariableStatement(node: VariableStatement, write: (node: Statement) => void): void {
if (node.flags & NodeFlags.Export) {
pipeNode(node.declarationList, transformVariableDeclarationListToExpressionStatement, write);
}
else {
write(node);
}
}
function transformVariableDeclarationListToExpressionStatement(node: VariableDeclarationList, write: (node: Statement) => void): void {
let expressions = mapNodes(node.declarations, transformVariableDeclarationToExpression);
if (expressions.length) {
write(createExpressionStatement(inlineExpressions(expressions)));
}
pipeNodes(node.declarations, emitVariableExportAssignments, write);
}
function transformVariableDeclarationToExpression(node: VariableDeclaration, write: (node: Expression) => void): void {
if (!node.initializer) {
return;
}
transformBindingElementToExpressionWithParenthesisIfNeeded(node, write, /*parenthesizeObjectLiteralAssignment*/ true);
}
/**
* @remarks
* This function is intended to be called from either `transformVariableDeclarationToExpression` or
* `transformBindingElementToExpression` and should not be called otherwise.
*/
function transformBindingElementToExpressionWithParenthesisIfNeeded(node: BindingElement, write: (node: Expression) => void, parenthesizeObjectLiteralAssignment?: boolean) {
let name = node.name;
let expr = isBindingPattern(name)
? mapNode(name, transformBindingPatternToExpression)
: createPropertyAccessExpression2(createIdentifier("exports"), makeSynthesized(name));
let initializer = node.initializer;
if (initializer) {
expr = createAssignmentExpression(expr, initializer, /*location*/ node);
}
if (parenthesizeObjectLiteralAssignment && isObjectBindingPattern(name)) {
expr = createParenthesizedExpression(expr);
}
else if (node.dotDotDotToken) {
expr = createSpreadElementExpression(expr);
}
write(expr);
}
/**
* @remarks
* This function is intended to be called from `transformVariableDeclarationToExpression` and should not be called otherwise.
*/
function transformBindingPatternToExpression(node: BindingPattern, write: (node: Expression) => void) {
switch (node.kind) {
case SyntaxKind.ObjectBindingPattern:
return transformObjectBindingPatternToExpression(<ObjectBindingPattern>node, write);
case SyntaxKind.ArrayBindingPattern:
return transformArrayBindingPatternToExpression(<ObjectBindingPattern>node, write);
}
}
/**
* @remarks
* This function is intended to be called from `transformBindingPatternToExpression` and should not be called otherwise.
*/
function transformObjectBindingPatternToExpression(node: ObjectBindingPattern, write: (node: Expression) => void) {
let properties = mapNodes(node.elements, transformBindingElementToObjectLiteralElement);
write(createObjectLiteralExpression(properties, /*location*/ node));
}
/**
* @remarks
* This function is intended to be called from `transformBindingPatternToExpression` and should not be called otherwise.
*/
function transformArrayBindingPatternToExpression(node: ArrayBindingPattern, write: (node: Expression) => void) {
let elements = mapNodes(node.elements, transformBindingElementToExpression);
write(createArrayLiteralExpression(elements, /*location*/ node));
}
/**
* @remarks
* This function is intended to be called from `transformObjectBindingPatternToExpression` and should not be called otherwise.
*/
function transformBindingElementToObjectLiteralElement(node: BindingElement, write: (node: ObjectLiteralElement) => void) {
let propertyName = node.propertyName || <Identifier>node.name;
let expr = mapNode(node, transformBindingElementToExpression);
write(createPropertyAssignment(propertyName, expr, /*location*/ node));
}
/**
* @remarks
* This function is intended to be called from `transformArrayBindingPatternToExpression` or
* `transformBindingElementToObjectLiteralElement` and should not be called otherwise.
*/
function transformBindingElementToExpression(node: BindingElement, write: (node: Expression) => void) {
transformBindingElementToExpressionWithParenthesisIfNeeded(node, write, /*parenthesizeObjectLiteralAssignment*/ false);
}
function emitVariableExportAssignments(node: VariableDeclaration | BindingElement, write: (node: Statement) => void): void {
let name = node.name;
if (isIdentifier(name)) {
emitExportMemberAssignments(name, write);
}
else if (isBindingPattern(name)) {
pipeNodes(name.elements, emitVariableExportAssignments, write);
}
}
function visitFunctionDeclaration(node: FunctionDeclaration, write: (node: Statement) => void): void {
const location: TextRange = node;
if (node.name) {
if (node.flags & NodeFlags.Export) {
write(createFunctionDeclaration2(node.name, node.parameters, node.body, location));
if (node.flags & NodeFlags.Default) {
emitExportDefault(makeSynthesized(node.name), location, write);
}
}
else {
write(node);
}
emitExportMemberAssignments(node.name, write);
}
else if (node.flags & NodeFlags.Default) {
emitExportDefault(createFunctionExpression3(node.parameters, node.body), location, write);
}
}
function visitClassDeclaration(node: ClassDeclaration, write: (node: Statement) => void): void {
const location: TextRange = node;
if (node.name) {
if (node.flags & NodeFlags.Export) {
write(createClassDeclaration2(node.name, getClassExtendsHeritageClauseElement(node), node.members, location));
if (node.flags & NodeFlags.Default) {
emitExportDefault(makeSynthesized(node.name), location, write);
}
}
else {
write(node);
}
emitExportMemberAssignments(node.name, write);
}
else if (node.flags & NodeFlags.Default) {
emitExportDefault(createClassExpression3(getClassExtendsHeritageClauseElement(node), node.members), location, write);
}
}
/**
* Substitution for identifiers exported at the top level of a module.
*/
function substituteExpressionWithFallback(node: Expression): Expression {
let substitute = substituteExpression(node);
return savedExpressionSubstution ? savedExpressionSubstution(substitute) : substitute;
}
function substituteExpression(node: Expression): Expression {
if (isIdentifier(node)) {
return substituteExpressionIdentifier(node);
}
return node;
}
function substituteExpressionIdentifier(node: Identifier): Expression {
let container = resolver.getReferencedExportContainer(node);
if (isSourceFile(container)) {
return createPropertyAccessExpression2(createIdentifier("exports"), makeSynthesized(node), /*location*/ node);
}
return node;
}
function tryCreateExportEquals(emitAsReturn: boolean) {
if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) {
if (emitAsReturn) {
return createReturnStatement(exportEquals.expression);
}
else {
let moduleExports = createPropertyAccessExpression3(createIdentifier("module"), "exports");
let exportExpression = createAssignmentExpression(moduleExports, exportEquals.expression);
return createExpressionStatement(exportExpression);
}
}
return undefined;
}
function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) {
let moduleName = getExternalModuleName(importNode);
if (isStringLiteral(moduleName)) {
return tryRenameExternalModule(moduleName) || makeSynthesized(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 createStringLiteral(currentSourceFile.renamedDependencies[moduleName.text]);
}
return undefined;
}
function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): Identifier {
let 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 getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
return <ImportEqualsDeclaration>node;
}
let importClause = (<ImportDeclaration>node).importClause;
if (importClause && importClause.namedBindings && importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
return <NamespaceImport>importClause.namedBindings;
}
}
function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
return isImportDeclaration(node) && node.importClause && !!node.importClause.name;
}
function createRequireCall(importNode: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
let moduleName = getExternalModuleNameLiteral(importNode);
return createCallExpression2(createIdentifier("require"), moduleName ? [moduleName] : []);
}
function emitExportAssignment(name: Identifier, value: Expression, location: TextRange, write: (node: Statement) => void) {
write(createExpressionStatement(createExportAssignment(name, value), location));
}
function createExportAssignment(name: Identifier, value: Expression) {
let exports = createIdentifier("exports");
let exportMember: LeftHandSideExpression;
if (name.originalKeywordKind && languageVersion === ScriptTarget.ES3) {
let exportName = createStringLiteral(name.text);
exportMember = createElementAccessExpression2(exports, exportName);
}
else {
let exportName = makeSynthesized(name);
exportMember = createPropertyAccessExpression2(exports, exportName);
}
return createAssignmentExpression(exportMember, value);
}
}
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver) {
let externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
let exportSpecifiers: Map<ExportSpecifier[]> = {};
let exportEquals: ExportAssignment = undefined;
let hasExportStars = false;
for (let node of sourceFile.statements) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
if (!(<ImportDeclaration>node).importClause ||
resolver.isReferencedAliasDeclaration((<ImportDeclaration>node).importClause, /*checkChildren*/ true)) {
// import "mod"
// import x from "mod" where x is referenced
// import * as x from "mod" where x is referenced
// import { x, y } from "mod" where at least one import is referenced
externalImports.push(<ImportDeclaration>node);
}
break;
case SyntaxKind.ImportEqualsDeclaration:
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) {
// import x = require("mod") where x is referenced
externalImports.push(<ImportEqualsDeclaration>node);
}
break;
case SyntaxKind.ExportDeclaration:
if ((<ExportDeclaration>node).moduleSpecifier) {
if (!(<ExportDeclaration>node).exportClause) {
// export * from "mod"
externalImports.push(<ExportDeclaration>node);
hasExportStars = true;
}
else if (resolver.isValueAliasDeclaration(node)) {
// export { x, y } from "mod" where at least one export is a value symbol
externalImports.push(<ExportDeclaration>node);
}
}
else {
// export { x, y }
for (let specifier of (<ExportDeclaration>node).exportClause.elements) {
let name = (specifier.propertyName || specifier.name).text;
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
}
}
break;
case SyntaxKind.ExportAssignment:
if ((<ExportAssignment>node).isExportEquals && !exportEquals) {
// export = x
exportEquals = <ExportAssignment>node;
}
break;
}
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStars };
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
/// <reference path="../checker.ts" />
/// <refernece path="./destructuring.ts" />
/*@internal*/
namespace ts {
export function createTypeScriptTransformation(transformer: Transformer): Transformation {
@ -38,8 +39,8 @@ namespace ts {
let exportSpecifiers: Map<ExportSpecifier[]>;
let exportEquals: ExportAssignment;
let exportFunctionForFile: string;
let savedSubstituteExpressionIdentifier = transformer.getExpressionIdentifierSubstitution();
transformer.setExpressionIdentifierSubstitution(substituteExpressionIdentifier);
let savedExpressionSubstution = transformer.getExpressionSubstitution();
transformer.setExpressionSubstitution(substituteExpressionWithFallback);
return transformTypeScript;
@ -58,7 +59,10 @@ namespace ts {
exportFunctionForFile = undefined;
currentSourceFile = node;
node = visitSourceFile(node, visitor);
let visited = visitSourceFile(node, visitor);
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitHelpersMask) {
transformer.setGeneratedNodeFlags(visited, GeneratedNodeFlags.EmitHelpers);
}
externalImports = undefined;
exportSpecifiers = undefined;
@ -66,7 +70,7 @@ namespace ts {
exportFunctionForFile = undefined;
currentSourceFile = undefined;
return node;
return visited;
}
/**
@ -465,7 +469,7 @@ namespace ts {
parameters = visitNodes(constructor.parameters, visitor, isParameter);
}
else if (baseTypeNode) {
parameters = [createRestParameter(createIdentifier("args"), /*location*/ undefined, NodeFlags.GeneratedRest)];
parameters = [createRestParameter(createIdentifier("args"), /*location*/ undefined, NodeFlags.Generated)];
}
// transform the body of the constructor
@ -996,7 +1000,7 @@ namespace ts {
}
let callExpr = createCallExpression2(parenExpr, [moduleParam]);
let callStmt = createExpressionStatement(callExpr, location, NodeFlags.GeneratedNamespace);
let callStmt = createExpressionStatement(callExpr, location, NodeFlags.Generated);
callStmt.original = node;
write(callStmt);
}
@ -1030,13 +1034,24 @@ namespace ts {
return !!(resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalModuleMergesWithClass);
}
function substituteExpressionIdentifier(node: Identifier): LeftHandSideExpression {
function substituteExpressionWithFallback(node: Expression): Expression {
let substitute = substituteExpression(node) || node;
return savedExpressionSubstution ? savedExpressionSubstution(substitute) : substitute;
}
function substituteExpression(node: Expression): Expression {
if (isIdentifier(node)) {
return substituteExpressionIdentifier(node);
}
return node;
}
function substituteExpressionIdentifier(node: Identifier): Expression {
let container = resolver.getReferencedExportContainer(node);
if (isModuleDeclaration(container)) {
return createPropertyAccessExpression2(getGeneratedNameForNode(container), node, node);
}
return savedSubstituteExpressionIdentifier ? savedSubstituteExpressionIdentifier(node) : node;
return node;
}
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration, write: (node: Statement) => void): void {
@ -1646,7 +1661,7 @@ namespace ts {
function createSynthesizedSuperCall() {
let callExpr = createCallExpression2(createSuperKeyword(), [createSpreadElementExpression(createIdentifier("args"))]);
return startOnNewLine(createExpressionStatement(callExpr, /*location*/ undefined, NodeFlags.GeneratedSuper));
return startOnNewLine(createExpressionStatement(callExpr, /*location*/ undefined, NodeFlags.Generated));
}
}
}

View File

@ -19,9 +19,12 @@
"binder.ts",
"checker.ts",
"transform.ts",
"transforms/module.ts",
"transforms/jsx.ts",
"transforms/destructuring.ts",
"transforms/ts.ts",
"transforms/module/module.ts",
"transforms/module/system.ts",
"transforms/module/es6.ts",
"transforms/jsx.ts",
"transforms/es6.ts",
"emitter.ts",
"program.ts",

View File

@ -383,9 +383,7 @@ namespace ts {
Namespace = 0x00020000, // Namespace declaration
ExportContext = 0x00040000, // Export context (initialized by binding)
ContainsThis = 0x00080000, // Interface contains references to "this"
GeneratedRest = 0x00100000, // Synthetic node generated during transformation
GeneratedSuper = 0x00200000, // Synthetic node generated during transformation
GeneratedNamespace =0x00400000, // Synthetic node generated during transformation
Generated = 0x00100000, // Synthetic node generated during transformation
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
AccessibilityModifier = Public | Private | Protected,
@ -433,14 +431,6 @@ namespace ts {
HasAggregatedChildData = 1 << 7
}
/* @internal */
export interface TransformResolver {
getGeneratedNameForNode(node: Node): string;
makeTempVariableName(loopVariable: boolean): string;
makeUniqueName(baseName: string): string;
getEmitResolver(): EmitResolver;
}
export const enum JsxFlags {
None = 0,
IntrinsicNamedElement = 1 << 0,
@ -702,6 +692,8 @@ namespace ts {
// @factoryhidden("decorators", true)
// @factoryhidden("modifiers", true)
// @factoryhidden("questionToken", true)
// @factoryhidden("equalsToken", true)
// @factoryhidden("objectAssignmentInitializer", true)
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
name: Identifier;
questionToken?: Node;
@ -2218,17 +2210,18 @@ namespace ts {
EmitParam = 0x00000020, // Emit __param helper for decorators
EmitAwaiter = 0x00000040, // Emit __awaiter
EmitGenerator = 0x00000080, // Emit __generator
EmitExportStar = 0x00000100, // Emit __export
SuperInstance = 0x00000200, // Instance 'super' reference
SuperStatic = 0x00000400, // Static 'super' reference
ContextChecked = 0x00000800, // Contextual types have been assigned
LexicalArguments = 0x00001000,
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body (for async functions)
SuperInstance = 0x00000100, // Instance 'super' reference
SuperStatic = 0x00000200, // Static 'super' reference
ContextChecked = 0x00000400, // Contextual types have been assigned
LexicalArguments = 0x00000800,
CaptureArguments = 0x00001000, // Lexical 'arguments' used in body (for async functions)
// Values for enum members have been computed, and any errors have been reported for them.
EnumValuesComputed = 0x00004000,
BlockScopedBindingInLoop = 0x00008000,
LexicalModuleMergesWithClass= 0x00010000, // Instantiated lexical module declaration is merged with a previous class declaration.
EnumValuesComputed = 0x00002000,
BlockScopedBindingInLoop = 0x00004000,
LexicalModuleMergesWithClass= 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
EmitHelpersMask = EmitExtends | EmitDecorate | EmitParam | EmitAwaiter | EmitGenerator,
}
/* @internal */
@ -3002,11 +2995,13 @@ namespace ts {
write(node: T): void;
}
// @internal
export type Transformation = (node: SourceFile) => SourceFile;
// @internal
export interface TransformationSubstitutions {
assignmentSubstitution: (node: BinaryExpression) => Expression;
expressionIdentifierSubstitution: (node: Identifier) => LeftHandSideExpression;
bindingIdentifierSubstitution: (node: Identifier) => Identifier;
getGeneratedNodeFlags(node: Node): GeneratedNodeFlags;
expressionSubstitution: (node: Expression) => Expression;
}
// @internal
@ -3015,60 +3010,372 @@ namespace ts {
substitutions?: TransformationSubstitutions;
}
// @internal
export const enum GeneratedNodeFlags {
EmitHelpers = 1 << 0,
EmitExportStar = 1 << 1,
UMDDefine = 1 << 2,
NoLexicalEnvironment = 1 << 3,
}
// @internal
export interface Transformer {
getEmitResolver(): EmitResolver;
getCompilerOptions(): CompilerOptions;
/**
* Generates a name unique to the source file given the provided base.
* @param baseName The base name.
*/
makeUniqueName(baseName: string): string;
/**
* Generates and caches a name unique to the node within the current lexical environment.
* @param The node for which to generate a name.
*/
getGeneratedNameForNode(node: Node): Identifier;
/**
* Gets a value indicating whether the provided node has a generated name.
* @param node The node to test.
*/
nodeHasGeneratedName(node: Node): boolean;
/**
* Generates an Identifier unique to the source file given the provided base.
* @param baseName The base name.
*/
createUniqueIdentifier(baseName: string): Identifier;
/**
* Generates an Identifier unique within the current lexical environment.
* @param flags A value that indicates flags used for temporary variable generation.
*/
createTempVariable(flags?: TempFlags): Identifier;
/**
* Creates a temporary variable using an optional base name and records it
* within the current lexical environment.
*
* This is the equivalent of:
* hoistVariableDeclaration(baseName ? createUniqueIdentifier(baseName) : createTempVariable());
*
* @param baseName An optional base name for the temporary variable.
*/
declareLocal(baseName?: string): Identifier;
/**
* Hoists the name of a variable declaration within a lexical environment.
*
* All hoisted variables are written during a call to endLexicalEnvironment.
*
* @param name The name of the declaration to hoist.
*/
hoistVariableDeclaration(name: Identifier): void;
/**
* Hoists a function declaration within the current lexical environment.
*
* All hoisted function declarations are written during a call to endLexicalEnvironment.
*
* @param func The function to hoist.
*/
hoistFunctionDeclaration(func: FunctionDeclaration): void;
createParentNavigator(): ParentNavigator;
getRootNode(): SourceFile;
getParentNode(): Node;
getCurrentNode(): Node;
tryPushNode(node: Node): boolean;
pushNode(node: Node): void;
popNode(): void;
findAncestorNode<T extends Node>(match: (node: Node) => node is T): T;
findAncestorNode(match: (node: Node) => boolean): Node;
createParentNavigator(): ParentNavigator; // from NodeStack
getRootNode(): SourceFile; // from NodeStack
getParentNode(): Node; // from NodeStack
getCurrentNode(): Node; // from NodeStack
tryPushNode(node: Node): boolean; // from NodeStack
pushNode(node: Node): void; // from NodeStack
popNode(): void; // from NodeStack
setNode(node: Node): void; // from NodeStack
findAncestorNode<T extends Node>(match: (node: Node) => node is T): T; // from NodeStack
findAncestorNode(match: (node: Node) => boolean): Node; // from NodeStack
// @deprecated
getDeclarationName(node: DeclarationStatement): Identifier;
// @deprecated
getDeclarationName(node: ClassLikeDeclaration): Identifier;
// @deprecated
getDeclarationName(node: Declaration): DeclarationName;
// @deprecated
getClassMemberPrefix(node: ClassLikeDeclaration, member: ClassElement): LeftHandSideExpression;
emitEmitHelpers(write: (node: Statement) => void): void;
emitExportStarHelper(write: (node: Statement) => void): void;
setGeneratedNodeFlags(node: Node, flags: GeneratedNodeFlags): void;
getGeneratedNodeFlags(node: Node): GeneratedNodeFlags;
getAssignmentSubstitution(): (node: BinaryExpression) => Expression;
setAssignmentSubstitution(substitution: (node: BinaryExpression) => Expression): void;
/**
* Rather than recurse deeply into a syntax tree to rewrite identifiers for exports
* or block-scoped declarations, you can establish a general substitution function to use
* for identifiers used in an expression position that will be invoked by the emitter
* when writing the final output.
*
* It is important to establish substitutions when a transformation phase is initialized,
* prior to the application of a transformation to any SourceFile.
*
* It is also important to capture any existing substituion to use as a fallback if the
* current transformation does not have work to do for an expression.
*
* @param substitution The callback used to substitute an identifier during emit.
*/
setExpressionSubstitution(substitution: (node: Expression) => Expression): void;
getExpressionIdentifierSubstitution(): (node: Identifier) => LeftHandSideExpression;
setExpressionIdentifierSubstitution(substitution: (node: Identifier) => LeftHandSideExpression): void;
getBindingIdentifierSubstitution(): (node: Identifier) => Identifier;
setBindingIdentifierSubstitution(substitution: (node: Identifier) => Identifier): void;
/**
* Gets any existing substitution for identifiers in an expression position.
*/
getExpressionSubstitution(): (node: Expression) => Expression;
/**
* Starts a new lexical environment, used to capture temporary and hoisted variables
* and hoisted function declarations.
*
* This function is the primary means to signify that the current transformation
* starts a new varible declaration scope.
*
* Lexical environments are implicitly started and ended by calls to the visitModuleBody,
* visitFunctionBody, visitConciseBody, and visitSourceFile functions.
*/
startLexicalEnvironment(): void;
/**
* Ends an existing lexical environment. Any temporary or hoisted variables or
* hoisted function declarations are written to the output.
*
* this function is the primary means to signify that the current transformation
* ends a variable declaration scope.
*
* Lexical environments are implicitly started and ended by calls to the visitModuleBody,
* visitFunctionBody, visitConciseBody, and visitSourceFile functions.
*
* @param out Either an array or a callback two which any declarations are written.
*/
endLexicalEnvironment(out: ((node: Statement) => void) | Statement[]): void;
pipeNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void, out: ((node: TOut) => void) | TOut[]): void;
pipeNodes<TIn extends Node, TOut extends Node>(node: TIn[], through: (node: TIn, write: (node: TOut) => void) => void, out: ((node: TOut) => void) | TOut[], start?: number, count?: number): void;
mapNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void): TOut;
mapNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], through: (node: TIn, write: (node: TOut) => void) => void, start?: number, count?: number): TOut[];
flattenNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void): TOut[];
/**
* Visits a syntax node using a general-purpose visitor callback.
*
* When visiting a single node, it is an error to write more than one output node.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is expected to be 1:1 (one-to-one).
*
* The node test is used to enforce that the output node matches the expected kind of the
* result.
*
* @param node The Node to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
* @param test A node test used to validate the result of visiting the node.
*/
visitNode<T extends Node>(node: T, visitor: (node: Node, write: (node: Node) => void) => void, test: (node: Node) => node is T): T;
/**
* Visits an array of syntax nodes using a general-purpose visitor callback.
*
* When visiting an array of nodes, it is acceptable to write more or less nodes to the output.
*
* If the same values are written in the same order as the original node array, the original
* node array is returned. If more or fewer values are written, or if any value differs from the source in order or reference
* equality, a new node array will be returned. This is to provide reference equality for the various update functions
* used by the accept function below.
*
* This function also ensures that each node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is expected to be *:* (many-to-many).
*
* The node test is used to enforce that each output node matches the expected kind of the
* result.
*
* @param nodes The array of Nodes to visit.
* @param visitor A callback executed to write the results of visiting each node or its children.
* @param test A node test used to validate the result of visiting each node.
* @param start An offset into nodes at which to start visiting.
* @param count A the number of nodes to visit.
*/
visitNodes<T extends Node>(nodes: T[], visitor: (node: Node, write: (node: Node) => void) => void, test: (node: Node) => node is T, start?: number, count?: number): NodeArray<T>;
/**
* A specialized variant of visitNode that permits writing multiple @{link Statement} nodes to
* the output, which are then enclosed enclosed in a Block.
*
* The cardinality of this function is 1:* (one-to-many).
*
* @param node The Statement to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
*/
visitStatement(node: Statement, visitor: (node: Node, write: (node: Node) => void) => void): Statement;
/**
* A specialized variant of visitNode that introduces a new lexical environment while visiting
* the body of a module, emitting any newly introduced temporary variables at the end of the body.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param node The ModuleBody to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
*/
visitModuleBody(node: ModuleBody, visitor: (node: Node, write: (node: Node) => void) => void): ModuleBody;
/**
* A specialized variant of visitNode that introduces a new lexical environment while visiting
* the body of a function, emitting any newly introduced temporary variables at the end of the body.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param node The FunctionBody to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
*/
visitFunctionBody(node: FunctionBody, visitor: (node: Node, write: (node: Node) => void) => void): FunctionBody;
/**
* A specialized variant of visitNode that introduces a new lexical environment while visiting
* the body of an arrow function.
*
* If the body is a Block, any newly introduced temporary variables will be added to the at the end of the body.
*
* If the body is an Expression and there are newly introduced temporary variables, the body will be converted
* into a Block with a ReturnStatement followed by the temporary declarations.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param node The ConciseBody to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
*/
visitConciseBody(node: ConciseBody, visitor: (node: Node, write: (node: Node) => void) => void): ConciseBody;
/**
* A specialized variant of visitNode that introduces a new lexical environment while visiting
* the body of a SourceFile, emitting any newly introduced temporary variables at the end of the file.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param node The SourceFile to visit.
* @param visitor A callback executed to write the results of visiting the node or its children.
*/
visitSourceFile(node: SourceFile, visitor: (node: Node, write: (node: Node) => void) => void): SourceFile;
/**
* For a given Node, visits each child of the node. If the results of visiting each child result in the
* exact same references as their inputs, the original value of the node parameter is returned. If any
* result differs from the input, a new Node of the same kind is returned with its children set to
* new values. This is to preserve the immutability of a syntax tree.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param node The Node to visit.
* @param visitor A callback executed to write the results of visiting the children of the node.
*/
accept<T extends Node>(node: T, visitor: (node: Node, write: (node: Node) => void) => void): T;
/**
* Pipes a single node through a callback used to write one or more nodes to the output.
*
* The output can be an array or a callback function used to write the output. Providing a
* callback as the output is the primary means to descend into a syntax tree while still
* writing output nodes to an outer visitor.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is 1:* (one-to-many).
*
* @param node The node to visit.
* @param through A special-purpose callback used to map a node of one kind to one or more nodes of another kind.
* @param out Either an array of nodes, or a callback used to write each node.
*/
pipeNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void, out: ((node: TOut) => void) | TOut[]): void;
/**
* Pipes a single node through a callback used to write one or more nodes to the output.
*
* The output can be an array or a callback function used to write the output. Providing a
* callback as the output is the primary means to descend into a syntax tree while still
* writing output nodes to an outer visitor.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is *:* (many-to-many).
*
* @param nodes The nodes to visit.
* @param through A special-purpose callback used to map a node of one kind to one or more nodes of another kind.
* @param out Either an array of nodes, or a callback used to write each node.
* @param start An offset into nodes at which to start visiting.
* @param count A the number of nodes to visit.
*/
pipeNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], through: (node: TIn, write: (node: TOut) => void) => void, out: ((node: TOut) => void) | TOut[], start?: number, count?: number): void;
/**
* A specialized variant of visitNode that uses a special-purposed callback function.
*
* When visiting a single node, it is an error to write more than one output node.
*
* While essentially the same as visitNode, this function enforces type safety through generics
* rather than a node test function, as the provided callback is typed to ensure input and output
* types are consistent. The callback is not intended to be a general-purpose routing/matching visitor.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* The return value is the result written via the callback supplied to the "through" parameter.
*
* @param node The node to visit.
* @param through A special-purpose callback used to map a node of one kind to a node of another kind.
*/
mapNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void): TOut;
/**
* A specialized variant of visitNodes that uses a special-purposed callback function.
*
* While similar to visitNodes, this function always returns a new array in its output.
* Also, this function enforces type safety through generics rather than a node test
* function, as the provided callback is typed to ensure input and output types are
* consistent. The callback is not intended to be a general-purpose routing/matching visitor.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is 1:1 (one-to-one).
*
* @param nodes The nodes to visit.
* @param through A special-purpose callback used to map a node of one kind to one or more nodes of another kind.
* @param start An offset into nodes at which to start visiting.
* @param count A the number of nodes to visit.
*/
mapNodes<TIn extends Node, TOut extends Node>(nodes: TIn[], through: (node: TIn, write: (node: TOut) => void) => void, start?: number, count?: number): TOut[];
/**
* A specialized version of visitNode/visitNodes that uses a special-purposed callback function.
*
* While similar to visitNode, it is acceptable to write multiple nodes to the output.
*
* Also, this function enforces type safety through generics rather than a node test
* function, as the provided callback is typed to ensure input and output types are
* consistent. The callback is not intended to be a general-purpose routing/matching visitor.
*
* This function also ensures that the node is pushed onto the node stack before calling the
* visitor, and popped off of the node stack once the visitor has returned.
*
* The cardinality of this function is 1:* (one-to-many).
*
* @param node The node to visit.
* @param through A special-purpose callback used to map a node of one kind to one or more nodes of another kind.
*/
flattenNode<TIn extends Node, TOut extends Node>(node: TIn, through: (node: TIn, write: (node: TOut) => void) => void): TOut[];
createNodes<TOut extends Node>(callback: (write: (node: TOut) => void) => void, out: ((node: TOut) => void) | TOut[]): void;
createNodes<TOut extends Node>(callback: (write: (node: TOut) => void) => void): NodeArray<TOut>;
}
export interface TextSpan {

View File

@ -406,7 +406,7 @@ namespace ts {
return !!(getCombinedNodeFlags(navigable) & NodeFlags.Let);
}
export function isPrologueDirective(node: Statement): boolean {
export function isPrologueDirective(node: Node): boolean {
return node.kind === SyntaxKind.ExpressionStatement && (<ExpressionStatement>node).expression.kind === SyntaxKind.StringLiteral;
}
@ -419,6 +419,11 @@ namespace ts {
return node;
}
export function getOriginalNodeId(node: Node) {
node = getOriginalNode(node);
return node ? getNodeId(node) : 0;
}
export function getOriginalNodeIf<T extends Node>(node: T, nodeTest: (node: Node) => node is T): T {
while (node && node.original) {
let original = node.original;
@ -2764,4 +2769,35 @@ namespace ts {
return arrayIsEqualTo(array1.sort(), array2.sort());
}
export function getLanguageVersion(compilerOptions: CompilerOptions) {
return compilerOptions.target || ScriptTarget.ES3;
}
export function getModuleKind(compilerOptions: CompilerOptions) {
if (compilerOptions.module) {
return compilerOptions.module;
}
switch (getLanguageVersion(compilerOptions)) {
case ScriptTarget.ES6: return ModuleKind.ES6;
case ScriptTarget.ES2015: return ModuleKind.ES2015;
}
return ModuleKind.None;
}
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
return <ImportEqualsDeclaration>node;
}
let importClause = (<ImportDeclaration>node).importClause;
if (importClause && importClause.namedBindings && importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
return <NamespaceImport>importClause.namedBindings;
}
}
export function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
return isImportDeclaration(node) && node.importClause && !!node.importClause.name;
}
}