mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 05:41:22 -06:00
Added support for System modules.
This commit is contained in:
parent
aa639d3ce7
commit
686c94cd67
16
Jakefile.js
16
Jakefile.js
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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
@ -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;
|
||||
|
||||
278
src/compiler/transforms/destructuring.ts
Normal file
278
src/compiler/transforms/destructuring.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
11
src/compiler/transforms/module/es6.ts
Normal file
11
src/compiler/transforms/module/es6.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
706
src/compiler/transforms/module/module.ts
Normal file
706
src/compiler/transforms/module/module.ts
Normal 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 };
|
||||
}
|
||||
}
|
||||
1156
src/compiler/transforms/module/system.ts
Normal file
1156
src/compiler/transforms/module/system.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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",
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user