Extract printer from emitter for reusability.
This commit is contained in:
parent
64dd8065aa
commit
028e4e2b13
|
@ -84,6 +84,7 @@ var compilerSources = [
|
|||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"declarationEmitter.ts",
|
||||
"printer.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
|
@ -121,6 +122,7 @@ var servicesSources = [
|
|||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"declarationEmitter.ts",
|
||||
"printer.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
|
|
|
@ -5,17 +5,13 @@ namespace ts {
|
|||
export interface CommentWriter {
|
||||
reset(): void;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
|
||||
emitTrailingCommentsOfPosition(pos: number): void;
|
||||
}
|
||||
|
||||
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
export function createCommentWriter(writer: EmitTextWriter, compilerOptions: CompilerOptions, newLine: string, emitPos: (pos: number) => void): CommentWriter {
|
||||
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
|
||||
const newLine = host.getNewLine();
|
||||
const { emitPos } = sourceMap;
|
||||
|
||||
let containerPos = -1;
|
||||
let containerEnd = -1;
|
||||
let declarationListContainerEnd = -1;
|
||||
|
@ -34,9 +30,9 @@ namespace ts {
|
|||
emitTrailingCommentsOfPosition,
|
||||
};
|
||||
|
||||
function emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (disabled) {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -47,11 +43,11 @@ namespace ts {
|
|||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -94,11 +90,11 @@ namespace ts {
|
|||
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
|
|
|
@ -35,13 +35,15 @@ namespace ts {
|
|||
forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
|
||||
return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
|
||||
|
||||
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) {
|
||||
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit, /*emitOnlyDtsFiles*/ false);
|
||||
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
|
||||
sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean): DeclarationEmit {
|
||||
sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean): DeclarationEmit {
|
||||
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
|
||||
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
|
||||
const newLine = host.getNewLine();
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
|
||||
|
@ -1803,8 +1805,9 @@ namespace ts {
|
|||
}
|
||||
return addedBundledEmitReference;
|
||||
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
|
||||
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
|
||||
if (isBundledEmit && !addBundledFileReference) {
|
||||
return;
|
||||
}
|
||||
|
@ -1817,10 +1820,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
/* @internal */
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit, emitOnlyDtsFiles);
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
|
||||
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
|
||||
if (!emitSkipped) {
|
||||
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
|
||||
const declarationOutput = emitDeclarationResult.referencesOutput
|
||||
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
||||
writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1530,6 +1530,19 @@ namespace ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
export function createBundle(sourceFiles: SourceFile[]) {
|
||||
const node = <Bundle>createNode(SyntaxKind.Bundle);
|
||||
node.sourceFiles = sourceFiles;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) {
|
||||
if (node.sourceFiles !== sourceFiles) {
|
||||
return createBundle(sourceFiles);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Compound nodes
|
||||
|
||||
export function createComma(left: Expression, right: Expression) {
|
||||
|
|
2659
src/compiler/printer.ts
Normal file
2659
src/compiler/printer.ts
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,10 +8,9 @@ namespace ts {
|
|||
*
|
||||
* @param filePath The path to the generated output file.
|
||||
* @param sourceMapFilePath The path to the output source map file.
|
||||
* @param sourceFiles The input source files for the program.
|
||||
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
|
||||
* @param sourceFileOrBundle The input source file or bundle for the program.
|
||||
*/
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle): void;
|
||||
|
||||
/**
|
||||
* Reset the SourceMapWriter to an empty state.
|
||||
|
@ -38,11 +37,11 @@ namespace ts {
|
|||
/**
|
||||
* Emits a node with possible leading and trailing source maps.
|
||||
*
|
||||
* @param emitContext The current emit context
|
||||
* @param hint The current emit context
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a token of a node node with possible leading and trailing source maps.
|
||||
|
@ -115,10 +114,9 @@ namespace ts {
|
|||
*
|
||||
* @param filePath The path to the generated output file.
|
||||
* @param sourceMapFilePath The path to the output source map file.
|
||||
* @param sourceFiles The input source files for the program.
|
||||
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
|
||||
* @param sourceFileOrBundle The input source file or bundle for the program.
|
||||
*/
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
@ -161,11 +159,10 @@ namespace ts {
|
|||
|
||||
if (compilerOptions.mapRoot) {
|
||||
sourceMapDir = normalizeSlashes(compilerOptions.mapRoot);
|
||||
if (!isBundledEmit) { // emitting single module file
|
||||
Debug.assert(sourceFiles.length === 1);
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) { // emitting single module file
|
||||
// For modules or multiple emit files the mapRoot will have directory structure like the sources
|
||||
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir));
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir));
|
||||
}
|
||||
|
||||
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
|
||||
|
@ -311,12 +308,13 @@ namespace ts {
|
|||
/**
|
||||
* Emits a node with possible leading and trailing source maps.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (disabled) {
|
||||
return emitCallback(emitContext, node);
|
||||
return emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (node) {
|
||||
|
@ -332,11 +330,11 @@ namespace ts {
|
|||
|
||||
if (emitFlags & EmitFlags.NoNestedSourceMaps) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (node.kind !== SyntaxKind.NotEmittedStatement
|
||||
|
|
|
@ -105,14 +105,16 @@ namespace ts {
|
|||
hoistFunctionDeclaration,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_emitContext, node) => node,
|
||||
onSubstituteNode: (_, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
|
||||
onEmitNode: (hint, node, callback) => callback(hint, node),
|
||||
enableEmitNotification,
|
||||
isEmitNotificationEnabled
|
||||
};
|
||||
|
||||
performance.mark("beforeTransform");
|
||||
|
||||
// Chain together and initialize each transformer.
|
||||
const transformation = chain(...transformers)(context);
|
||||
|
||||
|
@ -122,6 +124,9 @@ namespace ts {
|
|||
// Disable modification of the lexical environment.
|
||||
lexicalEnvironmentDisabled = true;
|
||||
|
||||
performance.mark("afterTransform");
|
||||
performance.measure("transformTime", "beforeTransform", "afterTransform");
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
|
@ -159,21 +164,16 @@ namespace ts {
|
|||
/**
|
||||
* Emits a node with possible substitution.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
const substitute = context.onSubstituteNode(emitContext, node);
|
||||
if (substitute && substitute !== node) {
|
||||
emitCallback(emitContext, substitute);
|
||||
return;
|
||||
}
|
||||
node = context.onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,17 +196,17 @@ namespace ts {
|
|||
/**
|
||||
* Emits a node with possible emit notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isEmitNotificationEnabled(node)) {
|
||||
context.onEmitNode(emitContext, node, emitCallback);
|
||||
context.onEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3435,9 +3435,11 @@ namespace ts {
|
|||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to be printed.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
|
||||
// If we are tracking a captured `this`, keep track of the enclosing function.
|
||||
const ancestorFacts = enterSubtree(
|
||||
|
@ -3445,11 +3447,11 @@ namespace ts {
|
|||
getEmitFlags(node) & EmitFlags.CapturesThis
|
||||
? HierarchyFacts.FunctionIncludes | HierarchyFacts.CapturesThis
|
||||
: HierarchyFacts.FunctionIncludes);
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
return;
|
||||
}
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3484,13 +3486,13 @@ namespace ts {
|
|||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param hint The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -396,33 +396,33 @@ namespace ts {
|
|||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
currentSuperContainer = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param isExpression A value indicating whether the node is to be used in an expression
|
||||
* position.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace ts {
|
|||
const compilerOptions = context.getCompilerOptions();
|
||||
|
||||
// enable emit notification only if using --jsx preserve or react-native
|
||||
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
let noSubstitution: boolean[];
|
||||
if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) {
|
||||
previousOnEmitNode = context.onEmitNode;
|
||||
|
@ -41,9 +41,11 @@ namespace ts {
|
|||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param node The node to be printed.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
|
@ -53,21 +55,21 @@ namespace ts {
|
|||
break;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
if (node.id && noSubstitution && noSubstitution[node.id]) {
|
||||
return previousOnSubstituteNode(emitContext, node);
|
||||
return previousOnSubstituteNode(hint, node);
|
||||
}
|
||||
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isPropertyAccessExpression(node)) {
|
||||
return substitutePropertyAccessExpression(node);
|
||||
}
|
||||
|
|
|
@ -1909,9 +1909,9 @@ namespace ts {
|
|||
return -1;
|
||||
}
|
||||
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node): Node {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node): Node {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
return node;
|
||||
|
|
|
@ -71,18 +71,18 @@ namespace ts {
|
|||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSourceFile = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,12 +93,12 @@ namespace ts {
|
|||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isIdentifier(node) && emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isIdentifier(node) && hint === EmitHint.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
}
|
||||
return node;
|
||||
|
|
|
@ -1207,24 +1207,24 @@ namespace ts {
|
|||
/**
|
||||
* Hook for node emit notifications.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
currentSourceFile = <SourceFile>node;
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
|
||||
noSubstitution = [];
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentModuleInfo = undefined;
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1235,16 +1235,16 @@ namespace ts {
|
|||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (node.id && noSubstitution[node.id]) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
else if (isShorthandPropertyAssignment(node)) {
|
||||
|
|
|
@ -1548,11 +1548,11 @@ namespace ts {
|
|||
/**
|
||||
* Hook for node emit notifications.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
* @param emitCallback A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
const id = getOriginalNodeId(node);
|
||||
currentSourceFile = <SourceFile>node;
|
||||
|
@ -1564,7 +1564,7 @@ namespace ts {
|
|||
delete noSubstitutionMap[id];
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
moduleInfo = undefined;
|
||||
|
@ -1572,7 +1572,7 @@ namespace ts {
|
|||
noSubstitution = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1583,16 +1583,16 @@ namespace ts {
|
|||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isSubstitutionPrevented(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
|
|
|
@ -3154,11 +3154,11 @@ namespace ts {
|
|||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
|
@ -3169,7 +3169,7 @@ namespace ts {
|
|||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
}
|
||||
|
@ -3177,12 +3177,12 @@ namespace ts {
|
|||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
else if (isShorthandPropertyAssignment(node)) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"comments.ts",
|
||||
"sourcemap.ts",
|
||||
"declarationEmitter.ts",
|
||||
"printer.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
|
|
|
@ -348,6 +348,7 @@
|
|||
EnumMember,
|
||||
// Top-level nodes
|
||||
SourceFile,
|
||||
Bundle,
|
||||
|
||||
// JSDoc nodes
|
||||
JSDocTypeExpression,
|
||||
|
@ -557,15 +558,6 @@
|
|||
|
||||
export type ModifiersArray = NodeArray<Modifier>;
|
||||
|
||||
/*@internal*/
|
||||
export const enum GeneratedIdentifierKind {
|
||||
None, // Not automatically generated.
|
||||
Auto, // Automatically generated identifier.
|
||||
Loop, // Automatically generated identifier with a preference for '_i'.
|
||||
Unique, // Unique name based on the 'text' property.
|
||||
Node, // Unique name based on the node in the 'original' property.
|
||||
}
|
||||
|
||||
export interface Identifier extends PrimaryExpression {
|
||||
kind: SyntaxKind.Identifier;
|
||||
text: string; // Text of identifier (with escapes converted to characters)
|
||||
|
@ -580,7 +572,14 @@
|
|||
resolvedSymbol: Symbol;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export const enum GeneratedIdentifierKind {
|
||||
None, // Not automatically generated.
|
||||
Auto, // Automatically generated identifier.
|
||||
Loop, // Automatically generated identifier with a preference for '_i'.
|
||||
Unique, // Unique name based on the 'text' property.
|
||||
Node, // Unique name based on the node in the 'original' property.
|
||||
}
|
||||
|
||||
export interface GeneratedIdentifier extends Identifier {
|
||||
autoGenerateKind: GeneratedIdentifierKind.Auto
|
||||
| GeneratedIdentifierKind.Loop
|
||||
|
@ -2201,6 +2200,11 @@
|
|||
/* @internal */ ambientModuleNames: string[];
|
||||
}
|
||||
|
||||
export interface Bundle extends Node {
|
||||
kind: SyntaxKind.Bundle;
|
||||
sourceFiles: SourceFile[];
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
|
@ -3780,8 +3784,7 @@
|
|||
LastEmitHelper = Generator
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum EmitContext {
|
||||
export const enum EmitHint {
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
|
@ -3856,7 +3859,7 @@
|
|||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
|
||||
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
|
@ -3874,7 +3877,7 @@
|
|||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
@ -3887,25 +3890,61 @@
|
|||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @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(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export interface EmitTextWriter {
|
||||
write(s: string): void;
|
||||
writeTextOfNode(text: string, node: Node): void;
|
||||
writeLine(): void;
|
||||
increaseIndent(): void;
|
||||
decreaseIndent(): void;
|
||||
getText(): string;
|
||||
rawWrite(s: string): void;
|
||||
writeLiteral(s: string): void;
|
||||
getTextPos(): number;
|
||||
getLine(): number;
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
isAtStartOfLine(): boolean;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
export interface Printer {
|
||||
printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): void;
|
||||
printFile(sourceFile: SourceFile): void;
|
||||
printBundle(bundle: Bundle): void;
|
||||
}
|
||||
|
||||
export interface PrinterOptions {
|
||||
hasGlobalName?: (name: string) => boolean;
|
||||
onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
|
||||
onEmitCommentsOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
onEmitDetachedCommentsOfNode?: (node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) => void;
|
||||
onEmitTrailingCommentsOfPosition?: (pos: number) => void;
|
||||
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void;
|
||||
onSetSourceFile?: (node: SourceFile) => void;
|
||||
onSubstituteNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
start: number;
|
||||
length: number;
|
||||
|
|
|
@ -2088,16 +2088,19 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
|
||||
const originalSourceFiles: SourceFile[] = [];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile);
|
||||
if (originalSourceFile) {
|
||||
originalSourceFiles.push(originalSourceFile);
|
||||
}
|
||||
export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
|
||||
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
|
||||
}
|
||||
return getOriginalSourceFile(sourceFileOrBundle);
|
||||
}
|
||||
|
||||
return originalSourceFiles;
|
||||
function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
|
||||
}
|
||||
|
||||
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
|
||||
return sameMap(sourceFiles, getOriginalSourceFile);
|
||||
}
|
||||
|
||||
export function getOriginalNodeId(node: Node) {
|
||||
|
@ -2436,23 +2439,6 @@ namespace ts {
|
|||
s;
|
||||
}
|
||||
|
||||
export interface EmitTextWriter {
|
||||
write(s: string): void;
|
||||
writeTextOfNode(text: string, node: Node): void;
|
||||
writeLine(): void;
|
||||
increaseIndent(): void;
|
||||
decreaseIndent(): void;
|
||||
getText(): string;
|
||||
rawWrite(s: string): void;
|
||||
writeLiteral(s: string): void;
|
||||
getTextPos(): number;
|
||||
getLine(): number;
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
isAtStartOfLine(): boolean;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
const indentStrings: string[] = ["", " "];
|
||||
export function getIndentString(level: number) {
|
||||
if (indentStrings[level] === undefined) {
|
||||
|
@ -2635,7 +2621,7 @@ namespace ts {
|
|||
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
|
||||
*/
|
||||
export function forEachEmittedFile(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
|
||||
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
|
||||
|
@ -2646,7 +2632,7 @@ namespace ts {
|
|||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles);
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -2654,7 +2640,7 @@ namespace ts {
|
|||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"../compiler/comments.ts",
|
||||
"../compiler/sourcemap.ts",
|
||||
"../compiler/declarationEmitter.ts",
|
||||
"../compiler/printer.ts",
|
||||
"../compiler/emitter.ts",
|
||||
"../compiler/program.ts",
|
||||
"../compiler/commandLineParser.ts",
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"../compiler/comments.ts",
|
||||
"../compiler/sourcemap.ts",
|
||||
"../compiler/declarationEmitter.ts",
|
||||
"../compiler/printer.ts",
|
||||
"../compiler/emitter.ts",
|
||||
"../compiler/program.ts",
|
||||
"../compiler/commandLineParser.ts",
|
||||
|
|
Loading…
Reference in a new issue