Merge pull request #13940 from Microsoft/publicTransformers
Expose public API for transformation.
This commit is contained in:
commit
ef25b25c1f
33 changed files with 1578 additions and 1047 deletions
|
@ -41,7 +41,7 @@ const {runTestsInParallel} = mochaParallel;
|
|||
Error.stackTraceLimit = 1000;
|
||||
|
||||
const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "light", "colors", "lint", "soft"],
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
|
||||
alias: {
|
||||
d: "debug",
|
||||
|
@ -57,6 +57,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
|||
soft: false,
|
||||
colors: process.env.colors || process.env.color || true,
|
||||
debug: process.env.debug || process.env.d,
|
||||
inspect: process.env.inspect,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
|
@ -597,6 +598,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
|||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
const light = cmdLineOptions["light"];
|
||||
const stackTraceLimit = cmdLineOptions["stackTraceLimit"];
|
||||
|
@ -633,7 +635,10 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
|||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
const args = [];
|
||||
if (debug) {
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
|
|
38
Jakefile.js
38
Jakefile.js
|
@ -131,6 +131,8 @@ var harnessSources = harnessCoreSources.concat([
|
|||
"matchFiles.ts",
|
||||
"initializeTSConfig.ts",
|
||||
"printer.ts",
|
||||
"transform.ts",
|
||||
"customTransforms.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
|
@ -792,6 +794,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
|||
}
|
||||
|
||||
var debug = process.env.debug || process.env.d;
|
||||
var inspect = process.env.inspect;
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var stackTraceLimit = process.env.stackTraceLimit;
|
||||
|
@ -821,18 +824,39 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
|||
testTimeout = 800000;
|
||||
}
|
||||
|
||||
colors = process.env.colors || process.env.color;
|
||||
colors = colors ? ' --no-colors ' : ' --colors ';
|
||||
reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = (process.env.bail || process.env.b) ? "--bail" : "";
|
||||
var colors = process.env.colors || process.env.color || true;
|
||||
var reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = process.env.bail || process.env.b;
|
||||
var lintFlag = process.env.lint !== 'false';
|
||||
|
||||
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
tests = tests ? ' -g "' + tests + '"' : '';
|
||||
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run;
|
||||
var args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (bail) {
|
||||
args.push("--bail");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
args.push(run);
|
||||
|
||||
var cmd = "mocha " + args.join(" ");
|
||||
console.log(cmd);
|
||||
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
|
@ -853,7 +877,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
|||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = "development";
|
||||
var startTime = mark();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) {
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: !colors }, function (err) {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
|
|
|
@ -64,6 +64,11 @@ namespace ts {
|
|||
undefinedSymbol.declarations = [];
|
||||
const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments");
|
||||
|
||||
// for public members that accept a Node or one of its subtypes, we must guard against
|
||||
// synthetic nodes created during transformations by calling `getParseTreeNode`.
|
||||
// for most of these, we perform the guard only on `checker` to avoid any possible
|
||||
// extra cost of calling `getParseTreeNode` when calling these functions from inside the
|
||||
// checker.
|
||||
const checker: TypeChecker = {
|
||||
getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
|
||||
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
|
||||
|
@ -74,8 +79,15 @@ namespace ts {
|
|||
isUnknownSymbol: symbol => symbol === unknownSymbol,
|
||||
getDiagnostics,
|
||||
getGlobalDiagnostics,
|
||||
getTypeOfSymbolAtLocation,
|
||||
getSymbolsOfParameterPropertyDeclaration,
|
||||
getTypeOfSymbolAtLocation: (symbol, location) => {
|
||||
location = getParseTreeNode(location);
|
||||
return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType;
|
||||
},
|
||||
getSymbolsOfParameterPropertyDeclaration: (parameter, parameterName) => {
|
||||
parameter = getParseTreeNode(parameter, isParameter);
|
||||
Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
|
||||
return getSymbolsOfParameterPropertyDeclaration(parameter, parameterName);
|
||||
},
|
||||
getDeclaredTypeOfSymbol,
|
||||
getPropertiesOfType,
|
||||
getPropertyOfType,
|
||||
|
@ -85,37 +97,88 @@ namespace ts {
|
|||
getBaseTypes,
|
||||
getBaseTypeOfLiteralType,
|
||||
getWidenedType,
|
||||
getTypeFromTypeNode,
|
||||
getTypeFromTypeNode: node => {
|
||||
node = getParseTreeNode(node, isTypeNode);
|
||||
return node ? getTypeFromTypeNode(node) : unknownType;
|
||||
},
|
||||
getParameterType: getTypeAtPosition,
|
||||
getReturnTypeOfSignature,
|
||||
getNonNullableType,
|
||||
getSymbolsInScope,
|
||||
getSymbolAtLocation,
|
||||
getShorthandAssignmentValueSymbol,
|
||||
getExportSpecifierLocalTargetSymbol,
|
||||
getTypeAtLocation: getTypeOfNode,
|
||||
getPropertySymbolOfDestructuringAssignment,
|
||||
signatureToString,
|
||||
typeToString,
|
||||
getSymbolsInScope: (location, meaning) => {
|
||||
location = getParseTreeNode(location);
|
||||
return location ? getSymbolsInScope(location, meaning) : [];
|
||||
},
|
||||
getSymbolAtLocation: node => {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getSymbolAtLocation(node) : undefined;
|
||||
},
|
||||
getShorthandAssignmentValueSymbol: node => {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getShorthandAssignmentValueSymbol(node) : undefined;
|
||||
},
|
||||
getExportSpecifierLocalTargetSymbol: node => {
|
||||
node = getParseTreeNode(node, isExportSpecifier);
|
||||
return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
|
||||
},
|
||||
getTypeAtLocation: node => {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getTypeOfNode(node) : unknownType;
|
||||
},
|
||||
getPropertySymbolOfDestructuringAssignment: location => {
|
||||
location = getParseTreeNode(location, isIdentifier);
|
||||
return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
|
||||
},
|
||||
signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => {
|
||||
return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind);
|
||||
},
|
||||
typeToString: (type, enclosingDeclaration?, flags?) => {
|
||||
return typeToString(type, getParseTreeNode(enclosingDeclaration), flags);
|
||||
},
|
||||
getSymbolDisplayBuilder,
|
||||
symbolToString,
|
||||
symbolToString: (symbol, enclosingDeclaration?, meaning?) => {
|
||||
return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning);
|
||||
},
|
||||
getAugmentedPropertiesOfType,
|
||||
getRootSymbols,
|
||||
getContextualType,
|
||||
getContextualType: node => {
|
||||
node = getParseTreeNode(node, isExpression)
|
||||
return node ? getContextualType(node) : undefined;
|
||||
},
|
||||
getFullyQualifiedName,
|
||||
getResolvedSignature,
|
||||
getConstantValue,
|
||||
isValidPropertyAccess,
|
||||
getSignatureFromDeclaration,
|
||||
isImplementationOfOverload,
|
||||
getResolvedSignature: (node, candidatesOutArray?) => {
|
||||
node = getParseTreeNode(node, isCallLikeExpression);
|
||||
return node ? getResolvedSignature(node, candidatesOutArray) : undefined;
|
||||
},
|
||||
getConstantValue: node => {
|
||||
node = getParseTreeNode(node, canHaveConstantValue);
|
||||
return node ? getConstantValue(node) : undefined;
|
||||
},
|
||||
isValidPropertyAccess: (node, propertyName) => {
|
||||
node = getParseTreeNode(node, isPropertyAccessOrQualifiedName);
|
||||
return node ? isValidPropertyAccess(node, propertyName) : false;
|
||||
},
|
||||
getSignatureFromDeclaration: declaration => {
|
||||
declaration = getParseTreeNode(declaration, isFunctionLike);
|
||||
return declaration ? getSignatureFromDeclaration(declaration) : undefined;
|
||||
},
|
||||
isImplementationOfOverload: node => {
|
||||
node = getParseTreeNode(node, isFunctionLike);
|
||||
return node ? isImplementationOfOverload(node) : undefined;
|
||||
},
|
||||
getAliasedSymbol: resolveAlias,
|
||||
getEmitResolver,
|
||||
getExportsOfModule: getExportsOfModuleAsArray,
|
||||
getExportsAndPropertiesOfModule,
|
||||
getAmbientModules,
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement,
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement: node => {
|
||||
node = getParseTreeNode(node, isJsxOpeningLikeElement);
|
||||
return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined;
|
||||
},
|
||||
getJsxIntrinsicTagNames,
|
||||
isOptionalParameter,
|
||||
isOptionalParameter: node => {
|
||||
node = getParseTreeNode(node, isParameter);
|
||||
return node ? isOptionalParameter(node) : false;
|
||||
},
|
||||
tryGetMemberInModuleExports,
|
||||
tryFindAmbientModuleWithoutAugmentations: moduleName => {
|
||||
// we deliberately exclude augmentations
|
||||
|
@ -20657,14 +20720,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
|
||||
const symbols = createMap<Symbol>();
|
||||
let memberFlags: ModifierFlags = ModifierFlags.None;
|
||||
|
||||
if (isInsideWithStatementBody(location)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return [];
|
||||
}
|
||||
|
||||
const symbols = createMap<Symbol>();
|
||||
let memberFlags: ModifierFlags = ModifierFlags.None;
|
||||
|
||||
populateSymbols();
|
||||
|
||||
return symbolsToArray(symbols);
|
||||
|
@ -20931,6 +20994,7 @@ namespace ts {
|
|||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
|
||||
}
|
||||
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
|
@ -21381,12 +21445,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isValueAliasDeclaration(node: Node): boolean {
|
||||
node = getParseTreeNode(node);
|
||||
if (node === undefined) {
|
||||
// A synthesized node comes from an emit transformation and is always a value.
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ImportClause:
|
||||
|
@ -21433,12 +21491,6 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
|
||||
node = getParseTreeNode(node);
|
||||
// Purely synthesized nodes are always emitted.
|
||||
if (node === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isAliasSymbolDeclaration(node)) {
|
||||
const symbol = getSymbolOfNode(node);
|
||||
if (symbol && getSymbolLinks(symbol).referenced) {
|
||||
|
@ -21481,8 +21533,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getNodeCheckFlags(node: Node): NodeCheckFlags {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getNodeLinks(node).flags : undefined;
|
||||
return getNodeLinks(node).flags;
|
||||
}
|
||||
|
||||
function getEnumMemberValue(node: EnumMember): number {
|
||||
|
@ -21490,6 +21541,16 @@ namespace ts {
|
|||
return getNodeLinks(node).enumMemberValue;
|
||||
}
|
||||
|
||||
function canHaveConstantValue(node: Node): node is EnumMember | PropertyAccessExpression | ElementAccessExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number {
|
||||
if (node.kind === SyntaxKind.EnumMember) {
|
||||
return getEnumMemberValue(<EnumMember>node);
|
||||
|
@ -21671,10 +21732,21 @@ namespace ts {
|
|||
getReferencedImportDeclaration,
|
||||
getReferencedDeclarationWithCollidingName,
|
||||
isDeclarationWithCollidingName,
|
||||
isValueAliasDeclaration,
|
||||
isValueAliasDeclaration: node => {
|
||||
node = getParseTreeNode(node);
|
||||
// Synthesized nodes are always treated like values.
|
||||
return node ? isValueAliasDeclaration(node) : true;
|
||||
},
|
||||
hasGlobalName,
|
||||
isReferencedAliasDeclaration,
|
||||
getNodeCheckFlags,
|
||||
isReferencedAliasDeclaration: (node, checkChildren?) => {
|
||||
node = getParseTreeNode(node);
|
||||
// Synthesized nodes are always treated as referenced.
|
||||
return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
|
||||
},
|
||||
getNodeCheckFlags: node => {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getNodeCheckFlags(node) : undefined;
|
||||
},
|
||||
isTopLevelValueImportEqualsWithEntityName,
|
||||
isDeclarationVisible,
|
||||
isImplementationOfOverload,
|
||||
|
@ -21685,7 +21757,10 @@ namespace ts {
|
|||
writeBaseConstructorTypeOfClass,
|
||||
isSymbolAccessible,
|
||||
isEntityNameVisible,
|
||||
getConstantValue,
|
||||
getConstantValue: node => {
|
||||
node = getParseTreeNode(node, canHaveConstantValue);
|
||||
return node ? getConstantValue(node) : undefined;
|
||||
},
|
||||
collectLinkedAliases,
|
||||
getReferencedValueDeclaration,
|
||||
getTypeReferenceSerializationKind,
|
||||
|
|
|
@ -43,18 +43,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (node) {
|
||||
const { pos, end } = getCommentRange(node);
|
||||
const emitFlags = getEmitFlags(node);
|
||||
hasWrittenComment = false;
|
||||
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const { pos, end } = emitNode && emitNode.commentRange || node;
|
||||
if ((pos < 0 && end < 0) || (pos === end)) {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
}
|
||||
else {
|
||||
if (extendedDiagnostics) {
|
||||
|
@ -94,17 +90,10 @@ namespace ts {
|
|||
performance.measure("commentTime", "preEmitNodeWithComment");
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beginEmitNodeWithComment");
|
||||
performance.mark("postEmitNodeWithComment");
|
||||
}
|
||||
|
||||
// Restore previous container state.
|
||||
|
@ -119,12 +108,88 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beginEmitNodeWithComment");
|
||||
performance.measure("commentTime", "postEmitNodeWithComment");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
const leadingComments = emitNode && emitNode.leadingComments;
|
||||
if (some(leadingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(leadingComments, emitLeadingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
|
||||
emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
|
||||
|
||||
const trailingComments = emitNode && emitNode.trailingComments;
|
||||
if (some(trailingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(trailingComments, emitTrailingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function writeSynthesizedComment(comment: SynthesizedComment) {
|
||||
const text = formatSynthesizedComment(comment);
|
||||
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
||||
writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
|
||||
}
|
||||
|
||||
function formatSynthesizedComment(comment: SynthesizedComment) {
|
||||
return comment.kind === SyntaxKind.MultiLineCommentTrivia
|
||||
? `/*${comment.text}*/`
|
||||
: `//${comment.text}`;
|
||||
}
|
||||
|
||||
function emitNodeWithNestedComments(hint: EmitHint, node: Node, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitBodyWithDetachedComments");
|
||||
|
|
|
@ -10,14 +10,13 @@ namespace ts {
|
|||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
|
||||
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
const newLine = host.getNewLine();
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(compilerOptions);
|
||||
const writer = createTextWriter(newLine);
|
||||
const sourceMap = createSourceMapWriter(host, writer);
|
||||
|
||||
|
@ -29,7 +28,7 @@ namespace ts {
|
|||
const sourceFiles = getSourceFilesToEmit(host, targetSourceFile);
|
||||
|
||||
// Transform the source files
|
||||
const transform = transformFiles(resolver, host, sourceFiles, transformers);
|
||||
const transform = transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
|
||||
|
||||
// Create a printer to print the nodes
|
||||
const printer = createPrinter(compilerOptions, {
|
||||
|
@ -38,7 +37,7 @@ namespace ts {
|
|||
|
||||
// transform hooks
|
||||
onEmitNode: transform.emitNodeWithNotification,
|
||||
onSubstituteNode: transform.emitNodeWithSubstitution,
|
||||
substituteNode: transform.substituteNode,
|
||||
|
||||
// sourcemap hooks
|
||||
onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
|
||||
|
@ -56,9 +55,7 @@ namespace ts {
|
|||
performance.measure("printTime", "beforePrint");
|
||||
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const sourceFile of sourceFiles) {
|
||||
disposeEmitNodes(sourceFile);
|
||||
}
|
||||
transform.dispose();
|
||||
|
||||
return {
|
||||
emitSkipped,
|
||||
|
@ -201,7 +198,7 @@ namespace ts {
|
|||
onEmitNode,
|
||||
onEmitHelpers,
|
||||
onSetSourceFile,
|
||||
onSubstituteNode,
|
||||
substituteNode,
|
||||
} = handlers;
|
||||
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
|
@ -331,8 +328,8 @@ namespace ts {
|
|||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
function emit(node: Node, hint = EmitHint.Unspecified) {
|
||||
pipelineEmitWithNotification(hint, node);
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
|
||||
function emitIdentifierName(node: Identifier) {
|
||||
|
@ -353,6 +350,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
node = trySubstituteNode(hint, node);
|
||||
if (emitNodeWithComments && hint !== EmitHint.SourceFile) {
|
||||
emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
|
||||
}
|
||||
|
@ -363,16 +361,7 @@ namespace ts {
|
|||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
if (onEmitSourceMapOfNode && hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName) {
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithSubstitution);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithSubstitution(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) {
|
||||
if (onSubstituteNode) {
|
||||
onSubstituteNode(hint, node, pipelineEmitWithHint);
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithHint(hint, node);
|
||||
|
@ -640,7 +629,7 @@ namespace ts {
|
|||
// If the node is an expression, try to emit it as an expression with
|
||||
// substitution.
|
||||
if (isExpression(node)) {
|
||||
return pipelineEmitWithSubstitution(EmitHint.Expression, node);
|
||||
return pipelineEmitExpression(trySubstituteNode(EmitHint.Expression, node));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -737,6 +726,10 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function trySubstituteNode(hint: EmitHint, node: Node) {
|
||||
return node && substituteNode && substituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(node, elements, emitCallback);
|
||||
|
@ -759,9 +752,6 @@ namespace ts {
|
|||
// SyntaxKind.NumericLiteral
|
||||
function emitNumericLiteral(node: NumericLiteral) {
|
||||
emitLiteral(node);
|
||||
if (node.trailingComment) {
|
||||
write(` /*${node.trailingComment}*/`);
|
||||
}
|
||||
}
|
||||
|
||||
// SyntaxKind.StringLiteral
|
||||
|
|
|
@ -215,7 +215,7 @@ namespace ts {
|
|||
|
||||
// Signature elements
|
||||
|
||||
export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) {
|
||||
export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) {
|
||||
const node = <ParameterDeclaration>createSynthesizedNode(SyntaxKind.Parameter);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -227,7 +227,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.dotDotDotToken !== dotDotDotToken
|
||||
|
@ -252,7 +252,7 @@ namespace ts {
|
|||
|
||||
// Type members
|
||||
|
||||
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression) {
|
||||
export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression) {
|
||||
const node = <PropertyDeclaration>createSynthesizedNode(SyntaxKind.PropertyDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -263,7 +263,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, type: TypeNode, initializer: Expression) {
|
||||
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, type: TypeNode | undefined, initializer: Expression) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -273,7 +273,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <MethodDeclaration>createSynthesizedNode(SyntaxKind.MethodDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -286,7 +286,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|
@ -299,7 +299,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) {
|
||||
export function createConstructor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
const node = <ConstructorDeclaration>createSynthesizedNode(SyntaxKind.Constructor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -310,7 +310,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) {
|
||||
export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.parameters !== parameters
|
||||
|
@ -319,7 +319,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createGetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <GetAccessorDeclaration>createSynthesizedNode(SyntaxKind.GetAccessor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -331,7 +331,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -342,7 +342,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block) {
|
||||
export function createSetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
const node = <SetAccessorDeclaration>createSynthesizedNode(SyntaxKind.SetAccessor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -353,7 +353,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) {
|
||||
export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -389,21 +389,21 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression) {
|
||||
export function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) {
|
||||
const node = <BindingElement>createSynthesizedNode(SyntaxKind.BindingElement);
|
||||
node.propertyName = asName(propertyName);
|
||||
node.dotDotDotToken = dotDotDotToken;
|
||||
node.propertyName = asName(propertyName);
|
||||
node.name = asName(name);
|
||||
node.initializer = initializer;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken, propertyName: PropertyName, name: BindingName, initializer: Expression) {
|
||||
export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.dotDotDotToken !== dotDotDotToken
|
||||
|| node.name !== name
|
||||
|| node.initializer !== initializer
|
||||
? updateNode(createBindingElement(propertyName, dotDotDotToken, name, initializer), node)
|
||||
? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function createCall(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) {
|
||||
const node = <CallExpression>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
|
@ -479,7 +479,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) {
|
||||
return expression !== node.expression
|
||||
|| typeArguments !== node.typeArguments
|
||||
|| argumentsArray !== node.arguments
|
||||
|
@ -487,7 +487,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function createNew(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) {
|
||||
const node = <NewExpression>createSynthesizedNode(SyntaxKind.NewExpression);
|
||||
node.expression = parenthesizeForNew(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
|
@ -495,7 +495,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) {
|
||||
return node.expression !== expression
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.arguments !== argumentsArray
|
||||
|
@ -543,7 +543,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createFunctionExpression(modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) {
|
||||
const node = <FunctionExpression>createSynthesizedNode(SyntaxKind.FunctionExpression);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.asteriskToken = asteriskToken;
|
||||
|
@ -555,7 +555,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], asteriskToken: AsteriskToken, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) {
|
||||
return node.name !== name
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|
@ -567,7 +567,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody) {
|
||||
export function createArrowFunction(modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody) {
|
||||
const node = <ArrowFunction>createSynthesizedNode(SyntaxKind.ArrowFunction);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.typeParameters = asNodeArray(typeParameters);
|
||||
|
@ -578,7 +578,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) {
|
||||
export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|
@ -722,9 +722,10 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateYield(node: YieldExpression, expression: Expression) {
|
||||
export function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createYield(node.asteriskToken, expression), node)
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
? updateNode(createYield(asteriskToken, expression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
@ -740,7 +741,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createClassExpression(modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function createClassExpression(modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
const node = <ClassExpression>createSynthesizedNode(SyntaxKind.ClassExpression);
|
||||
node.decorators = undefined;
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -751,7 +752,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateClassExpression(node: ClassExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function updateClassExpression(node: ClassExpression, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|| node.typeParameters !== typeParameters
|
||||
|
@ -836,7 +837,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[]): VariableStatement {
|
||||
export function createVariableStatement(modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList | VariableDeclaration[]) {
|
||||
const node = <VariableStatement>createSynthesizedNode(SyntaxKind.VariableStatement);
|
||||
node.decorators = undefined;
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -844,14 +845,14 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement {
|
||||
export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.declarationList !== declarationList
|
||||
? updateNode(createVariableStatement(modifiers, declarationList), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList {
|
||||
export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags) {
|
||||
const node = <VariableDeclarationList>createSynthesizedNode(SyntaxKind.VariableDeclarationList);
|
||||
node.flags |= flags;
|
||||
node.declarations = createNodeArray(declarations);
|
||||
|
@ -864,7 +865,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration {
|
||||
export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression) {
|
||||
const node = <VariableDeclaration>createSynthesizedNode(SyntaxKind.VariableDeclaration);
|
||||
node.name = asName(name);
|
||||
node.type = type;
|
||||
|
@ -872,7 +873,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) {
|
||||
return node.name !== name
|
||||
|| node.type !== type
|
||||
|| node.initializer !== initializer
|
||||
|
@ -884,7 +885,7 @@ namespace ts {
|
|||
return <EmptyStatement>createSynthesizedNode(SyntaxKind.EmptyStatement);
|
||||
}
|
||||
|
||||
export function createStatement(expression: Expression): ExpressionStatement {
|
||||
export function createStatement(expression: Expression) {
|
||||
const node = <ExpressionStatement>createSynthesizedNode(SyntaxKind.ExpressionStatement);
|
||||
node.expression = parenthesizeExpressionForExpressionStatement(expression);
|
||||
return node;
|
||||
|
@ -904,7 +905,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) {
|
||||
export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) {
|
||||
return node.expression !== expression
|
||||
|| node.thenStatement !== thenStatement
|
||||
|| node.elseStatement !== elseStatement
|
||||
|
@ -940,7 +941,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) {
|
||||
export function createFor(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) {
|
||||
const node = <ForStatement>createSynthesizedNode(SyntaxKind.ForStatement);
|
||||
node.initializer = initializer;
|
||||
node.condition = condition;
|
||||
|
@ -949,7 +950,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateFor(node: ForStatement, initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) {
|
||||
export function updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) {
|
||||
return node.initializer !== initializer
|
||||
|| node.condition !== condition
|
||||
|| node.incrementor !== incrementor
|
||||
|
@ -998,7 +999,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateContinue(node: ContinueStatement, label: Identifier) {
|
||||
export function updateContinue(node: ContinueStatement, label: Identifier | undefined) {
|
||||
return node.label !== label
|
||||
? updateNode(createContinue(label), node)
|
||||
: node;
|
||||
|
@ -1010,7 +1011,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateBreak(node: BreakStatement, label: Identifier) {
|
||||
export function updateBreak(node: BreakStatement, label: Identifier | undefined) {
|
||||
return node.label !== label
|
||||
? updateNode(createBreak(label), node)
|
||||
: node;
|
||||
|
@ -1022,7 +1023,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateReturn(node: ReturnStatement, expression: Expression) {
|
||||
export function updateReturn(node: ReturnStatement, expression: Expression | undefined) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createReturn(expression), node)
|
||||
: node;
|
||||
|
@ -1082,7 +1083,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) {
|
||||
export function createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) {
|
||||
const node = <TryStatement>createSynthesizedNode(SyntaxKind.TryStatement);
|
||||
node.tryBlock = tryBlock;
|
||||
node.catchClause = catchClause;
|
||||
|
@ -1090,7 +1091,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) {
|
||||
export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) {
|
||||
return node.tryBlock !== tryBlock
|
||||
|| node.catchClause !== catchClause
|
||||
|| node.finallyBlock !== finallyBlock
|
||||
|
@ -1098,7 +1099,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <FunctionDeclaration>createSynthesizedNode(SyntaxKind.FunctionDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1111,7 +1112,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|
@ -1124,7 +1125,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function createClassDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
const node = <ClassDeclaration>createSynthesizedNode(SyntaxKind.ClassDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1135,7 +1136,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -1146,7 +1147,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createEnumDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, members: EnumMember[]) {
|
||||
export function createEnumDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, members: EnumMember[]) {
|
||||
const node = <EnumDeclaration>createSynthesizedNode(SyntaxKind.EnumDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1155,7 +1156,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, members: EnumMember[]) {
|
||||
export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, members: EnumMember[]) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -1164,7 +1165,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createModuleDeclaration(decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody, flags?: NodeFlags) {
|
||||
export function createModuleDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) {
|
||||
const node = <ModuleDeclaration>createSynthesizedNode(SyntaxKind.ModuleDeclaration);
|
||||
node.flags |= flags;
|
||||
node.decorators = asNodeArray(decorators);
|
||||
|
@ -1174,7 +1175,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody) {
|
||||
export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -1207,7 +1208,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createImportEqualsDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, moduleReference: ModuleReference) {
|
||||
export function createImportEqualsDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) {
|
||||
const node = <ImportEqualsDeclaration>createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1216,7 +1217,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, moduleReference: ModuleReference) {
|
||||
export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|
@ -1225,7 +1226,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression): ImportDeclaration {
|
||||
export function createImportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier?: Expression): ImportDeclaration {
|
||||
const node = <ImportDeclaration>createSynthesizedNode(SyntaxKind.ImportDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1234,7 +1235,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) {
|
||||
export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier
|
||||
|
@ -1280,21 +1281,21 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createImportSpecifier(propertyName: Identifier, name: Identifier) {
|
||||
export function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier) {
|
||||
const node = <ImportSpecifier>createSynthesizedNode(SyntaxKind.ImportSpecifier);
|
||||
node.propertyName = propertyName;
|
||||
node.name = name;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) {
|
||||
export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.name !== name
|
||||
? updateNode(createImportSpecifier(propertyName, name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression) {
|
||||
export function createExportAssignment(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, isExportEquals: boolean, expression: Expression) {
|
||||
const node = <ExportAssignment>createSynthesizedNode(SyntaxKind.ExportAssignment);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1303,7 +1304,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) {
|
||||
export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, expression: Expression) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.expression !== expression
|
||||
|
@ -1311,7 +1312,7 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression) {
|
||||
export function createExportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier?: Expression) {
|
||||
const node = <ExportDeclaration>createSynthesizedNode(SyntaxKind.ExportDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
|
@ -1320,7 +1321,7 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) {
|
||||
export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.exportClause !== exportClause
|
||||
|
@ -1341,16 +1342,17 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier) {
|
||||
export function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier) {
|
||||
const node = <ExportSpecifier>createSynthesizedNode(SyntaxKind.ExportSpecifier);
|
||||
node.name = asName(name);
|
||||
node.propertyName = asName(propertyName);
|
||||
node.name = asName(name);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateExportSpecifier(node: ExportSpecifier, name: Identifier, propertyName: Identifier) {
|
||||
return node.name !== name || node.propertyName !== propertyName
|
||||
? updateNode(createExportSpecifier(name, propertyName), node)
|
||||
export function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.name !== name
|
||||
? updateNode(createExportSpecifier(propertyName, name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
@ -1465,16 +1467,16 @@ namespace ts {
|
|||
: node;
|
||||
}
|
||||
|
||||
export function createJsxExpression(expression: Expression, dotDotDotToken: DotDotDotToken) {
|
||||
export function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) {
|
||||
const node = <JsxExpression>createSynthesizedNode(SyntaxKind.JsxExpression);
|
||||
node.dotDotDotToken = dotDotDotToken;
|
||||
node.expression = expression;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxExpression(node: JsxExpression, expression: Expression) {
|
||||
export function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createJsxExpression(expression, node.dotDotDotToken), node)
|
||||
? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
@ -1552,26 +1554,26 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) {
|
||||
const node = <ShorthandPropertyAssignment>createSynthesizedNode(SyntaxKind.ShorthandPropertyAssignment);
|
||||
node.name = asName(name);
|
||||
node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) {
|
||||
if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) {
|
||||
return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpreadAssignment(expression), node);
|
||||
|
@ -1779,7 +1781,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function createExternalModuleExport(exportName: Identifier) {
|
||||
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)]));
|
||||
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
@ -1860,7 +1862,7 @@ namespace ts {
|
|||
/**
|
||||
* Gets flags that control emit behavior of a node.
|
||||
*/
|
||||
export function getEmitFlags(node: Node) {
|
||||
export function getEmitFlags(node: Node): EmitFlags | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.flags;
|
||||
}
|
||||
|
@ -1884,7 +1886,7 @@ namespace ts {
|
|||
/**
|
||||
* Sets a custom text range to use when emitting source maps.
|
||||
*/
|
||||
export function setSourceMapRange<T extends Node>(node: T, range: TextRange) {
|
||||
export function setSourceMapRange<T extends Node>(node: T, range: TextRange | undefined) {
|
||||
getOrCreateEmitNode(node).sourceMapRange = range;
|
||||
return node;
|
||||
}
|
||||
|
@ -1892,7 +1894,7 @@ namespace ts {
|
|||
/**
|
||||
* Gets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges[token];
|
||||
|
@ -1901,7 +1903,7 @@ namespace ts {
|
|||
/**
|
||||
* Sets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange) {
|
||||
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange | undefined) {
|
||||
const emitNode = getOrCreateEmitNode(node);
|
||||
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
|
||||
tokenSourceMapRanges[token] = range;
|
||||
|
@ -1924,6 +1926,34 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.leadingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticLeadingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
getOrCreateEmitNode(node).leadingComments = comments;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function addSyntheticLeadingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
|
||||
return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), <SynthesizedComment>{ kind, pos: -1, end: -1, hasTrailingNewLine, text }));
|
||||
}
|
||||
|
||||
export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.trailingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
getOrCreateEmitNode(node).trailingComments = comments;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function addSyntheticTrailingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
|
||||
return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), <SynthesizedComment>{ kind, pos: -1, end: -1, hasTrailingNewLine, text }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constant value to emit for an expression.
|
||||
*/
|
||||
|
@ -2024,7 +2054,7 @@ namespace ts {
|
|||
return compareValues(x.priority, y.priority);
|
||||
}
|
||||
|
||||
export function setOriginalNode<T extends Node>(node: T, original: Node): T {
|
||||
export function setOriginalNode<T extends Node>(node: T, original: Node | undefined): T {
|
||||
node.original = original;
|
||||
if (original) {
|
||||
const emitNode = original.emitNode;
|
||||
|
@ -2036,6 +2066,8 @@ namespace ts {
|
|||
function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) {
|
||||
const {
|
||||
flags,
|
||||
leadingComments,
|
||||
trailingComments,
|
||||
commentRange,
|
||||
sourceMapRange,
|
||||
tokenSourceMapRanges,
|
||||
|
@ -2043,6 +2075,8 @@ namespace ts {
|
|||
helpers
|
||||
} = sourceEmitNode;
|
||||
if (!destEmitNode) destEmitNode = {};
|
||||
if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments);
|
||||
if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments);
|
||||
if (flags) destEmitNode.flags = flags;
|
||||
if (commentRange) destEmitNode.commentRange = commentRange;
|
||||
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;
|
||||
|
|
|
@ -5832,7 +5832,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
|
||||
const range = {
|
||||
kind: <SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia>triviaScanner.getToken(),
|
||||
pos: triviaScanner.getTokenPos(),
|
||||
end: triviaScanner.getTextPos(),
|
||||
};
|
||||
|
||||
const comment = sourceText.substring(range.pos, range.end);
|
||||
const referencePathMatchResult = getFileReferenceFromReferencePath(comment, range);
|
||||
|
|
|
@ -754,15 +754,15 @@ namespace ts {
|
|||
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
|
||||
}
|
||||
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles));
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers));
|
||||
}
|
||||
|
||||
function isEmitBlocked(emitFileName: string): boolean {
|
||||
return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: Diagnostic[] = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
|
@ -804,11 +804,13 @@ namespace ts {
|
|||
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers);
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile,
|
||||
emitOnlyDtsFiles);
|
||||
emitOnlyDtsFiles,
|
||||
transformers);
|
||||
|
||||
performance.mark("afterEmit");
|
||||
performance.measure("Emit", "beforeEmit", "afterEmit");
|
||||
|
|
|
@ -608,10 +608,10 @@ namespace ts {
|
|||
* @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
|
||||
* return value of the callback.
|
||||
*/
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
let pendingPos: number;
|
||||
let pendingEnd: number;
|
||||
let pendingKind: SyntaxKind;
|
||||
let pendingKind: CommentKind;
|
||||
let pendingHasTrailingNewLine: boolean;
|
||||
let hasPendingCommentRange = false;
|
||||
let collecting = trailing || pos === 0;
|
||||
|
@ -707,28 +707,28 @@ namespace ts {
|
|||
return accumulator;
|
||||
}
|
||||
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
|
||||
}
|
||||
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
|
||||
}
|
||||
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
|
||||
}
|
||||
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
|
||||
}
|
||||
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
if (!comments) {
|
||||
comments = [];
|
||||
}
|
||||
|
||||
comments.push({ pos, end, hasTrailingNewLine, kind });
|
||||
comments.push({ kind, pos, end, hasTrailingNewLine });
|
||||
return comments;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): Transformer {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile> {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.ES2015:
|
||||
return transformES2015Module;
|
||||
|
@ -24,16 +24,25 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const enum TransformationState {
|
||||
Uninitialized,
|
||||
Initialized,
|
||||
Completed,
|
||||
Disposed
|
||||
}
|
||||
|
||||
const enum SyntaxKindFeatureFlags {
|
||||
Substitution = 1 << 0,
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions) {
|
||||
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers) {
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const transformers: Transformer[] = [];
|
||||
const transformers: TransformerFactory<SourceFile>[] = [];
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.before);
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
|
||||
|
@ -66,6 +75,8 @@ namespace ts {
|
|||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.after);
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
|
@ -73,28 +84,29 @@ namespace ts {
|
|||
* Transforms an array of SourceFiles by passing them through each transformer.
|
||||
*
|
||||
* @param resolver The emit resolver provided by the checker.
|
||||
* @param host The emit host.
|
||||
* @param sourceFiles An array of source files
|
||||
* @param transforms An array of Transformers.
|
||||
* @param host The emit host object used to interact with the file system.
|
||||
* @param options Compiler options to surface in the `TransformationContext`.
|
||||
* @param nodes An array of nodes to transform.
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
|
||||
let lexicalEnvironmentDisabled = false;
|
||||
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
|
||||
let emitHelpers: EmitHelper[];
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
|
||||
let state = TransformationState.Uninitialized;
|
||||
|
||||
// The transformation context is provided to each transformer as part of transformer
|
||||
// initialization.
|
||||
const context: TransformationContext = {
|
||||
getCompilerOptions: () => host.getCompilerOptions(),
|
||||
getCompilerOptions: () => options,
|
||||
getEmitResolver: () => resolver,
|
||||
getEmitHost: () => host,
|
||||
startLexicalEnvironment,
|
||||
|
@ -105,51 +117,62 @@ namespace ts {
|
|||
hoistFunctionDeclaration,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (hint, node, callback) => callback(hint, node),
|
||||
enableEmitNotification,
|
||||
isEmitNotificationEnabled
|
||||
isSubstitutionEnabled,
|
||||
isEmitNotificationEnabled,
|
||||
get onSubstituteNode() { return onSubstituteNode },
|
||||
set onSubstituteNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onSubstituteNode = value;
|
||||
},
|
||||
get onEmitNode() { return onEmitNode },
|
||||
set onEmitNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onEmitNode = value;
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure the parse tree is clean before applying transformations
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
performance.mark("beforeTransform");
|
||||
|
||||
// Chain together and initialize each transformer.
|
||||
const transformation = chain(...transformers)(context);
|
||||
|
||||
// Transform each source file.
|
||||
const transformed = map(sourceFiles, transformSourceFile);
|
||||
// prevent modification of transformation hooks.
|
||||
state = TransformationState.Initialized;
|
||||
|
||||
// Disable modification of the lexical environment.
|
||||
lexicalEnvironmentDisabled = true;
|
||||
// Transform each node.
|
||||
const transformed = map(nodes, allowDtsFiles ? transformation : transformRoot);
|
||||
|
||||
// prevent modification of the lexical environment.
|
||||
state = TransformationState.Completed;
|
||||
|
||||
performance.mark("afterTransform");
|
||||
performance.measure("transformTime", "beforeTransform", "afterTransform");
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
emitNodeWithNotification
|
||||
substituteNode,
|
||||
emitNodeWithNotification,
|
||||
dispose
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms a source file.
|
||||
*
|
||||
* @param sourceFile The source file to transform.
|
||||
*/
|
||||
function transformSourceFile(sourceFile: SourceFile) {
|
||||
if (isDeclarationFile(sourceFile)) {
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
return transformation(sourceFile);
|
||||
function transformRoot(node: T) {
|
||||
return node && (!isSourceFile(node) || !isDeclarationFile(node)) ? transformation(node) : node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableSubstitution(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.Substitution;
|
||||
}
|
||||
|
||||
|
@ -168,19 +191,16 @@ namespace ts {
|
|||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
node = context.onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
function substituteNode(hint: EmitHint, node: Node) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed.");
|
||||
return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableEmitNotification(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.EmitNotifications;
|
||||
}
|
||||
|
||||
|
@ -201,9 +221,10 @@ namespace ts {
|
|||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed.");
|
||||
if (node) {
|
||||
if (isEmitNotificationEnabled(node)) {
|
||||
context.onEmitNode(hint, node, emitCallback);
|
||||
onEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
|
@ -215,7 +236,8 @@ namespace ts {
|
|||
* Records a hoisted variable declaration for the provided name within a lexical environment.
|
||||
*/
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
const decl = createVariableDeclaration(name);
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
|
@ -229,7 +251,8 @@ namespace ts {
|
|||
* Records a hoisted function declaration within a lexical environment.
|
||||
*/
|
||||
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
if (!lexicalEnvironmentFunctionDeclarations) {
|
||||
lexicalEnvironmentFunctionDeclarations = [func];
|
||||
}
|
||||
|
@ -243,7 +266,8 @@ namespace ts {
|
|||
* are pushed onto a stack, and the related storage variables are reset.
|
||||
*/
|
||||
function startLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot start a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
// Save the current lexical environment. Rather than resizing the array we adjust the
|
||||
|
@ -259,14 +283,16 @@ namespace ts {
|
|||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
function suspendLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot suspend a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
|
||||
lexicalEnvironmentSuspended = true;
|
||||
}
|
||||
|
||||
/** Resumes a suspended lexical environment, usually before visiting a function body. */
|
||||
function resumeLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot resume a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
|
||||
lexicalEnvironmentSuspended = false;
|
||||
}
|
||||
|
@ -276,7 +302,8 @@ namespace ts {
|
|||
* any hoisted declarations added in this environment are returned.
|
||||
*/
|
||||
function endLexicalEnvironment(): Statement[] {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot end a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
let statements: Statement[];
|
||||
|
@ -312,16 +339,39 @@ namespace ts {
|
|||
}
|
||||
|
||||
function requestEmitHelper(helper: EmitHelper): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
|
||||
emitHelpers = append(emitHelpers, helper);
|
||||
}
|
||||
|
||||
function readEmitHelpers(): EmitHelper[] | undefined {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
const helpers = emitHelpers;
|
||||
emitHelpers = undefined;
|
||||
return helpers;
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
if (state < TransformationState.Disposed) {
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
// Release references to external entries for GC purposes.
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarationsStack = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarationsStack = undefined;
|
||||
onSubstituteNode = undefined;
|
||||
onEmitNode = undefined;
|
||||
emitHelpers = undefined;
|
||||
|
||||
// Prevent further use of the transformation result.
|
||||
state = TransformationState.Disposed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -467,7 +467,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function makeBindingElement(name: Identifier) {
|
||||
return createBindingElement(/*propertyName*/ undefined, /*dotDotDotToken*/ undefined, name);
|
||||
return createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
|
||||
}
|
||||
|
||||
function makeAssignmentElement(name: Identifier) {
|
||||
|
|
|
@ -2321,7 +2321,7 @@ namespace ts {
|
|||
addRange(statements, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
const statement = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
const statement = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
|
@ -2679,7 +2679,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
|
@ -3674,7 +3674,7 @@ namespace ts {
|
|||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const original = getParseTreeNode(node, isIdentifier);
|
||||
if (original && isNameOfDeclarationWithCollidingName(original)) {
|
||||
return getGeneratedNameForNode(original);
|
||||
return setTextRange(getGeneratedNameForNode(original), node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3727,7 +3727,7 @@ namespace ts {
|
|||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
|
||||
if (declaration) {
|
||||
return getGeneratedNameForNode(declaration.name);
|
||||
return setTextRange(getGeneratedNameForNode(declaration.name), node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ namespace ts {
|
|||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
return updateYield(
|
||||
node,
|
||||
node.asteriskToken,
|
||||
node.asteriskToken
|
||||
? createAsyncDelegatorHelper(context, expression, expression)
|
||||
: createArrayLiteral(
|
||||
|
|
|
@ -1230,7 +1230,7 @@ namespace ts {
|
|||
case SyntaxKind.TryStatement:
|
||||
return transformAndEmitTryStatement(<TryStatement>node);
|
||||
default:
|
||||
return emitStatement(visitNode(node, visitor, isStatement, /*optional*/ true));
|
||||
return emitStatement(visitNode(node, visitor, isStatement));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1488,9 +1488,9 @@ namespace ts {
|
|||
variables.length > 0
|
||||
? inlineExpressions(map(variables, transformInitializedVariable))
|
||||
: undefined,
|
||||
visitNode(node.condition, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -1612,7 +1612,7 @@ namespace ts {
|
|||
node = updateForIn(node,
|
||||
<Identifier>initializer.declarations[0].name,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -1662,14 +1662,14 @@ namespace ts {
|
|||
|
||||
function transformAndEmitReturnStatement(node: ReturnStatement): void {
|
||||
emitReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
||||
function visitReturnStatement(node: ReturnStatement) {
|
||||
return createInlineReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
@ -2422,7 +2422,7 @@ namespace ts {
|
|||
*/
|
||||
function createInstruction(instruction: Instruction): NumericLiteral {
|
||||
const literal = createLiteral(instruction);
|
||||
literal.trailingComment = getInstructionName(instruction);
|
||||
addSyntheticTrailingComment(literal, SyntaxKind.MultiLineCommentTrivia, getInstructionName(instruction));
|
||||
return literal;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace ts {
|
|||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
@ -383,7 +383,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Visit each statement of the module body.
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
|
||||
// Append the 'export =' statement if provided.
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace ts {
|
|||
);
|
||||
|
||||
// Visit the synthetic external helpers import declaration if present
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true);
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement);
|
||||
|
||||
// Visit the statements of the source file, emitting any transformations into
|
||||
// the `executeStatements` array. We do this *before* we fill the `setters` array
|
||||
|
@ -1219,8 +1219,8 @@ namespace ts {
|
|||
node = updateFor(
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement)
|
||||
);
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ namespace ts {
|
|||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
|
@ -1262,7 +1262,7 @@ namespace ts {
|
|||
node.awaitModifier,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
|
@ -1307,7 +1307,7 @@ namespace ts {
|
|||
function visitDoStatement(node: DoStatement): VisitResult<Statement> {
|
||||
return updateDo(
|
||||
node,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression)
|
||||
);
|
||||
}
|
||||
|
@ -1321,7 +1321,7 @@ namespace ts {
|
|||
return updateWhile(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1334,7 @@ namespace ts {
|
|||
return updateLabel(
|
||||
node,
|
||||
node.label,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1347,7 +1347,7 @@ namespace ts {
|
|||
return updateWith(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2842,7 +2842,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Elide the declaration if the import clause was elided.
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause, /*optional*/ true);
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause);
|
||||
return importClause
|
||||
? updateImportDeclaration(
|
||||
node,
|
||||
|
@ -2861,7 +2861,7 @@ namespace ts {
|
|||
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
|
||||
// Elide the import clause if we elide both its name and its named bindings.
|
||||
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings, /*optional*/ true);
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
|
||||
return (name || namedBindings) ? updateImportClause(node, name, namedBindings) : undefined;
|
||||
}
|
||||
|
||||
|
@ -2923,7 +2923,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Elide the export declaration if all of its named exports are elided.
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports, /*optional*/ true);
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports);
|
||||
return exportClause
|
||||
? updateExportDeclaration(
|
||||
node,
|
||||
|
@ -3327,17 +3327,18 @@ namespace ts {
|
|||
function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression {
|
||||
const constantValue = tryGetConstEnumValue(node);
|
||||
if (constantValue !== undefined) {
|
||||
// track the constant value on the node for the printer in needsDotDotForPropertyAccess
|
||||
setConstantValue(node, constantValue);
|
||||
|
||||
const substitute = createLiteral(constantValue);
|
||||
setSourceMapRange(substitute, node);
|
||||
setCommentRange(substitute, node);
|
||||
if (!compilerOptions.removeComments) {
|
||||
const propertyName = isPropertyAccessExpression(node)
|
||||
? declarationNameToString(node.name)
|
||||
: getTextOfNode(node.argumentExpression);
|
||||
substitute.trailingComment = ` ${propertyName} `;
|
||||
|
||||
addSyntheticTrailingComment(substitute, SyntaxKind.MultiLineCommentTrivia, ` ${propertyName} `);
|
||||
}
|
||||
|
||||
setConstantValue(node, constantValue);
|
||||
return substitute;
|
||||
}
|
||||
|
||||
|
|
|
@ -1323,7 +1323,6 @@
|
|||
|
||||
export interface NumericLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.NumericLiteral;
|
||||
trailingComment?: string;
|
||||
}
|
||||
|
||||
export interface TemplateHead extends LiteralLikeNode {
|
||||
|
@ -1907,9 +1906,17 @@
|
|||
fileName: string;
|
||||
}
|
||||
|
||||
export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia;
|
||||
|
||||
export interface CommentRange extends TextRange {
|
||||
hasTrailingNewLine?: boolean;
|
||||
kind: SyntaxKind;
|
||||
kind: CommentKind;
|
||||
}
|
||||
|
||||
export interface SynthesizedComment extends CommentRange {
|
||||
text: string;
|
||||
pos: -1;
|
||||
end: -1;
|
||||
}
|
||||
|
||||
// represents a top level: { type } expression in a JSDoc comment.
|
||||
|
@ -2294,7 +2301,7 @@
|
|||
* used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter
|
||||
* will be invoked when writing the JavaScript and declaration files.
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
|
@ -2328,6 +2335,13 @@
|
|||
/* @internal */ structureIsReused?: boolean;
|
||||
}
|
||||
|
||||
export interface CustomTransformers {
|
||||
/** Custom transformers to evaluate before built-in transformations. */
|
||||
before?: TransformerFactory<SourceFile>[];
|
||||
/** Custom transformers to evaluate after built-in transformations. */
|
||||
after?: TransformerFactory<SourceFile>[];
|
||||
}
|
||||
|
||||
export interface SourceMapSpan {
|
||||
/** Line number in the .js file. */
|
||||
emittedLine: number;
|
||||
|
@ -3789,9 +3803,11 @@
|
|||
export interface EmitNode {
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
leadingComments?: SynthesizedComment[]; // Synthesized leading comments
|
||||
trailingComments?: SynthesizedComment[]; // Synthesized trailing comments
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens
|
||||
tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
|
@ -3827,7 +3843,7 @@
|
|||
|
||||
export interface EmitHelper {
|
||||
readonly name: string; // A unique name for this helper.
|
||||
readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope.
|
||||
readonly scoped: boolean; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
readonly text: string; // ES3-compatible raw script text.
|
||||
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
|
||||
}
|
||||
|
@ -3889,11 +3905,12 @@
|
|||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationContext {
|
||||
/*@internal*/ getEmitResolver(): EmitResolver;
|
||||
/*@internal*/ getEmitHost(): EmitHost;
|
||||
|
||||
/** Gets the compiler options supplied to the transformer. */
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/** Starts a new lexical environment. */
|
||||
startLexicalEnvironment(): void;
|
||||
|
@ -3907,41 +3924,32 @@
|
|||
/** Ends a lexical environment, returning any declarations. */
|
||||
endLexicalEnvironment(): Statement[];
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
/** Hoists a function declaration to the containing scope. */
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
/** Hoists a variable declaration to the containing scope. */
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Records a request for a non-scoped emit helper in the current context.
|
||||
*/
|
||||
/** Records a request for a non-scoped emit helper in the current context. */
|
||||
requestEmitHelper(helper: EmitHelper): void;
|
||||
|
||||
/**
|
||||
* Gets and resets the requested non-scoped emit helpers.
|
||||
*/
|
||||
/** Gets and resets the requested non-scoped emit helpers. */
|
||||
readEmitHelpers(): EmitHelper[] | undefined;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
/** Enables expression substitutions in the pretty printer for the provided SyntaxKind. */
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
/** Determines whether expression substitutions are enabled for the provided node. */
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*
|
||||
* NOTE: Transformation hooks should only be modified during `Transformer` initialization,
|
||||
* before returning the `NodeTransformer` callback.
|
||||
*/
|
||||
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
|
||||
onSubstituteNode: (hint: EmitHint, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
|
@ -3958,25 +3966,27 @@
|
|||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*
|
||||
* NOTE: Transformation hooks should only be modified during `Transformer` initialization,
|
||||
* before returning the `NodeTransformer` callback.
|
||||
*/
|
||||
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationResult {
|
||||
/**
|
||||
* Gets the transformed source files.
|
||||
*/
|
||||
transformed: SourceFile[];
|
||||
export interface TransformationResult<T extends Node> {
|
||||
/** Gets the transformed source files. */
|
||||
transformed: T[];
|
||||
|
||||
/** Gets diagnostics for the transformation. */
|
||||
diagnostics?: Diagnostic[];
|
||||
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode(hint: EmitHint, node: Node): Node;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
|
@ -3986,10 +3996,30 @@
|
|||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Clean up EmitNode entries on any parse-tree nodes.
|
||||
*/
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
/**
|
||||
* A function that is used to initialize and return a `Transformer` callback, which in turn
|
||||
* will be used to transform one or more nodes.
|
||||
*/
|
||||
export type TransformerFactory<T extends Node> = (context: TransformationContext) => Transformer<T>;
|
||||
|
||||
/**
|
||||
* A function that transforms a node.
|
||||
*/
|
||||
export type Transformer<T extends Node> = (node: T) => T;
|
||||
|
||||
/**
|
||||
* A function that accepts and possible transforms a node.
|
||||
*/
|
||||
export type Visitor = (node: Node) => VisitResult<Node>;
|
||||
|
||||
export type VisitResult<T extends Node> = T | T[];
|
||||
|
||||
export interface Printer {
|
||||
/**
|
||||
|
@ -4047,23 +4077,20 @@
|
|||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
|
||||
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
|
||||
* the provided `node`, or its substitute.
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`.
|
||||
* @param hint A hint indicating the intended purpose of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback that, when invoked, will emit the node.
|
||||
* @example
|
||||
* ```ts
|
||||
* var printer = createPrinter(printerOptions, {
|
||||
* onSubstituteNode(hint, node, emitCallback) {
|
||||
* substituteNode(hint, node) {
|
||||
* // perform substitution if necessary...
|
||||
* emitCallback(hint, node);
|
||||
* return node;
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode?(hint: EmitHint, node: Node): Node;
|
||||
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
|
|
|
@ -3799,6 +3799,12 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
|
||||
export function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.PropertyAccessExpression
|
||||
|| kind === SyntaxKind.QualifiedName;
|
||||
}
|
||||
|
||||
export function isElementAccessExpression(node: Node): node is ElementAccessExpression {
|
||||
return node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
|
@ -4149,16 +4155,18 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.JsxAttribute;
|
||||
}
|
||||
|
||||
export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement {
|
||||
return node.kind === SyntaxKind.JsxOpeningElement || node.kind === SyntaxKind.JsxSelfClosingElement;
|
||||
}
|
||||
|
||||
export function isStringLiteralOrJsxExpression(node: Node): node is StringLiteral | JsxExpression {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.JsxExpression;
|
||||
}
|
||||
|
||||
export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxOpeningElement
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement;
|
||||
}
|
||||
|
||||
// Clauses
|
||||
|
||||
export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause {
|
||||
|
@ -4608,7 +4616,7 @@ namespace ts {
|
|||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (isParseTreeNode(node)) {
|
||||
if (node == undefined || isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -77,8 +77,8 @@
|
|||
"../services/codefixes/helpers.ts",
|
||||
"../services/codefixes/importFixes.ts",
|
||||
"../services/codefixes/unusedIdentifierFixes.ts",
|
||||
"../services/harness.ts",
|
||||
|
||||
"harness.ts",
|
||||
"sourceMapRecorder.ts",
|
||||
"harnessLanguageService.ts",
|
||||
"fourslash.ts",
|
||||
|
@ -119,6 +119,8 @@
|
|||
"./unittests/compileOnSave.ts",
|
||||
"./unittests/typingsInstaller.ts",
|
||||
"./unittests/projectErrors.ts",
|
||||
"./unittests/printer.ts"
|
||||
"./unittests/printer.ts",
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts"
|
||||
]
|
||||
}
|
||||
|
|
86
src/harness/unittests/customTransforms.ts
Normal file
86
src/harness/unittests/customTransforms.ts
Normal file
|
@ -0,0 +1,86 @@
|
|||
/// <reference path="..\..\compiler\emitter.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("customTransforms", () => {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
|
||||
it(name, () => {
|
||||
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
|
||||
const fileMap = arrayToMap(roots, file => file.fileName);
|
||||
const outputs = createMap<string>();
|
||||
const options: CompilerOptions = {};
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName) => fileMap.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
getCurrentDirectory: () => "",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: (fileName) => fileName,
|
||||
useCaseSensitiveFileNames: () => true,
|
||||
getNewLine: () => "\n",
|
||||
fileExists: (fileName) => fileMap.has(fileName),
|
||||
readFile: (fileName) => fileMap.has(fileName) ? fileMap.get(fileName).text : undefined,
|
||||
writeFile: (fileName, text) => outputs.set(fileName, text),
|
||||
};
|
||||
|
||||
const program = createProgram(arrayFrom(fileMap.keys()), options, host);
|
||||
program.emit(/*targetSourceFile*/ undefined, host.writeFile, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ false, customTransformers);
|
||||
Harness.Baseline.runBaseline(`customTransforms/${name}.js`, () => {
|
||||
let content = "";
|
||||
for (const [file, text] of arrayFrom(outputs.entries())) {
|
||||
if (content) content += "\n\n";
|
||||
content += `// [${file}]\n`;
|
||||
content += text;
|
||||
}
|
||||
return content;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const sources = [{
|
||||
file: "source.ts",
|
||||
text: `
|
||||
function f1() { }
|
||||
class c() { }
|
||||
enum e { }
|
||||
// leading
|
||||
function f2() { } // trailing
|
||||
`
|
||||
}];
|
||||
|
||||
const before: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return visitFunction(<FunctionDeclaration>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitFunction(node: FunctionDeclaration) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, "@before", /*hasTrailingNewLine*/ true);
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
const after: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatement(<VariableStatement>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitVariableStatement(node: VariableStatement) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, "@after");
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
emitsCorrectly("before", sources, { before: [before] });
|
||||
emitsCorrectly("after", sources, { after: [after] });
|
||||
emitsCorrectly("both", sources, { before: [before], after: [after] });
|
||||
});
|
||||
}
|
43
src/harness/unittests/transform.ts
Normal file
43
src/harness/unittests/transform.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/// <reference path="..\..\services\transform.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("TransformAPI", () => {
|
||||
function transformsCorrectly(name: string, source: string, transformers: TransformerFactory<SourceFile>[]) {
|
||||
it(name, () => {
|
||||
Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${name}.js`, () => {
|
||||
const transformed = transform(createSourceFile("source.ts", source, ScriptTarget.ES2015), transformers);
|
||||
const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, {
|
||||
onEmitNode: transformed.emitNodeWithNotification,
|
||||
substituteNode: transformed.substituteNode
|
||||
});
|
||||
const result = printer.printBundle(createBundle(transformed.transformed));
|
||||
transformed.dispose();
|
||||
return result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
transformsCorrectly("substitution", `
|
||||
var a = undefined;
|
||||
`, [
|
||||
context => {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
context.onSubstituteNode = (hint, node) => {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "undefined") {
|
||||
node = createPartiallyEmittedExpression(
|
||||
addSyntheticTrailingComment(
|
||||
setTextRange(
|
||||
createVoidZero(),
|
||||
node),
|
||||
SyntaxKind.MultiLineCommentTrivia, "undefined"));
|
||||
}
|
||||
return node;
|
||||
};
|
||||
return file => file;
|
||||
}
|
||||
]);
|
||||
});
|
||||
}
|
|
@ -67,10 +67,10 @@ namespace ts.OutliningElementsCollector {
|
|||
|
||||
// Only outline spans of two or more consecutive single line comments
|
||||
if (count > 1) {
|
||||
const multipleSingleLineComments = {
|
||||
const multipleSingleLineComments: CommentRange = {
|
||||
kind: SyntaxKind.SingleLineCommentTrivia,
|
||||
pos: start,
|
||||
end: end,
|
||||
kind: SyntaxKind.SingleLineCommentTrivia
|
||||
};
|
||||
|
||||
addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
|
||||
|
|
|
@ -1447,7 +1447,8 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles);
|
||||
const customTransformers = host.getCustomTransformers && host.getCustomTransformers();
|
||||
const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
|
|
18
src/services/transform.ts
Normal file
18
src/services/transform.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// <reference path="..\compiler\transformer.ts"/>
|
||||
/// <reference path="transpile.ts"/>
|
||||
namespace ts {
|
||||
/**
|
||||
* Transform one or more nodes using the supplied transformers.
|
||||
* @param source A single `Node` or an array of `Node` objects.
|
||||
* @param transformers An array of `TransformerFactory` callbacks used to process the transformation.
|
||||
* @param compilerOptions Optional compiler options.
|
||||
*/
|
||||
export function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions) {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
compilerOptions = fixupCompilerOptions(compilerOptions, diagnostics);
|
||||
const nodes = isArray(source) ? source : [source];
|
||||
const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
|
||||
result.diagnostics = concatenate(result.diagnostics, diagnostics);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -123,7 +123,8 @@
|
|||
let commandLineOptionsStringToEnum: CommandLineOptionOfCustomType[];
|
||||
|
||||
/** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */
|
||||
function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions {
|
||||
/*@internal*/
|
||||
export function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions {
|
||||
// Lazily create this value to fix module loading errors.
|
||||
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o =>
|
||||
typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number"));
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
"preProcess.ts",
|
||||
"rename.ts",
|
||||
"services.ts",
|
||||
"transform.ts",
|
||||
"transpile.ts",
|
||||
"shims.ts",
|
||||
"signatureHelp.ts",
|
||||
|
|
|
@ -170,6 +170,11 @@ namespace ts {
|
|||
* completions will not be provided
|
||||
*/
|
||||
getDirectories?(directoryName: string): string[];
|
||||
|
||||
/**
|
||||
* Gets a set of custom transformers to use during emit.
|
||||
*/
|
||||
getCustomTransformers?(): CustomTransformers | undefined;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
15
tests/baselines/reference/customTransforms/after.js
Normal file
15
tests/baselines/reference/customTransforms/after.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
// [source.js]
|
||||
function f1() { }
|
||||
//@after
|
||||
var c = (function () {
|
||||
function c() {
|
||||
}
|
||||
return c;
|
||||
}());
|
||||
(function () { });
|
||||
//@after
|
||||
var e;
|
||||
(function (e) {
|
||||
})(e || (e = {}));
|
||||
// leading
|
||||
function f2() { } // trailing
|
15
tests/baselines/reference/customTransforms/before.js
Normal file
15
tests/baselines/reference/customTransforms/before.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
// [source.js]
|
||||
/*@before*/
|
||||
function f1() { }
|
||||
var c = (function () {
|
||||
function c() {
|
||||
}
|
||||
return c;
|
||||
}());
|
||||
(function () { });
|
||||
var e;
|
||||
(function (e) {
|
||||
})(e || (e = {}));
|
||||
// leading
|
||||
/*@before*/
|
||||
function f2() { } // trailing
|
17
tests/baselines/reference/customTransforms/both.js
Normal file
17
tests/baselines/reference/customTransforms/both.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
// [source.js]
|
||||
/*@before*/
|
||||
function f1() { }
|
||||
//@after
|
||||
var c = (function () {
|
||||
function c() {
|
||||
}
|
||||
return c;
|
||||
}());
|
||||
(function () { });
|
||||
//@after
|
||||
var e;
|
||||
(function (e) {
|
||||
})(e || (e = {}));
|
||||
// leading
|
||||
/*@before*/
|
||||
function f2() { } // trailing
|
|
@ -0,0 +1 @@
|
|||
var a = void 0 /*undefined*/;
|
Loading…
Reference in a new issue