mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Merged some changes from other branches.
This commit is contained in:
@@ -222,6 +222,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
|
||||
}
|
||||
|
||||
var useDebugMode = true;
|
||||
var useTransforms = process.env.USE_TRANSFORMS || false;
|
||||
var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node");
|
||||
var compilerFilename = "tsc.js";
|
||||
var LKGCompiler = path.join(LKGDirectory, compilerFilename);
|
||||
@@ -281,6 +282,10 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu
|
||||
options += " --stripInternal"
|
||||
}
|
||||
|
||||
if (useBuiltCompiler && useTransforms) {
|
||||
options += " --experimentalTransforms"
|
||||
}
|
||||
|
||||
var cmd = host + " " + compilerPath + " " + options + " ";
|
||||
cmd = cmd + sources.join(" ");
|
||||
console.log(cmd + "\n");
|
||||
@@ -404,6 +409,10 @@ task("setDebugMode", function() {
|
||||
useDebugMode = true;
|
||||
});
|
||||
|
||||
task("setTransforms", function() {
|
||||
useTransforms = true;
|
||||
});
|
||||
|
||||
task("configure-nightly", [configureNightlyJs], function() {
|
||||
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs;
|
||||
console.log(cmd);
|
||||
|
||||
@@ -5,11 +5,15 @@ namespace ts {
|
||||
export interface CommentWriter {
|
||||
reset(): void;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
getLeadingCommentsToEmit(node: TextRange): CommentRange[];
|
||||
getTrailingCommentsToEmit(node: TextRange): CommentRange[];
|
||||
emitDetachedComments(node: TextRange): void;
|
||||
emitLeadingComments(node: TextRange, comments?: CommentRange[]): void;
|
||||
emitTrailingComments(node: TextRange, comments?: CommentRange[]): void;
|
||||
getLeadingComments(range: Node, getAdditionalRange?: (range: Node) => Node): CommentRange[];
|
||||
getLeadingComments(range: TextRange): CommentRange[];
|
||||
getLeadingCommentsOfPosition(pos: number): CommentRange[];
|
||||
getTrailingComments(range: Node, getAdditionalRange?: (range: Node) => Node): CommentRange[];
|
||||
getTrailingComments(range: TextRange): CommentRange[];
|
||||
getTrailingCommentsOfPosition(pos: number): CommentRange[];
|
||||
emitLeadingComments(range: TextRange, comments?: CommentRange[]): void;
|
||||
emitTrailingComments(range: TextRange, comments?: CommentRange[]): void;
|
||||
emitDetachedComments(range: TextRange): void;
|
||||
}
|
||||
|
||||
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
|
||||
@@ -25,8 +29,8 @@ namespace ts {
|
||||
// This maps start->end for a comment range. See `hasConsumedCommentRange` and
|
||||
// `consumeCommentRange` for usage.
|
||||
let consumedCommentRanges: number[];
|
||||
let leadingCommentRangeNodeStarts: boolean[];
|
||||
let trailingCommentRangeNodeEnds: boolean[];
|
||||
let leadingCommentRangePositions: boolean[];
|
||||
let trailingCommentRangePositions: boolean[];
|
||||
|
||||
return compilerOptions.removeComments
|
||||
? createCommentRemovingWriter()
|
||||
@@ -36,11 +40,13 @@ namespace ts {
|
||||
return {
|
||||
reset,
|
||||
setSourceFile,
|
||||
getLeadingCommentsToEmit(node: TextRange): CommentRange[] { return undefined; },
|
||||
getTrailingCommentsToEmit(node: TextRange): CommentRange[] { return undefined; },
|
||||
getLeadingComments(range: TextRange, getAdditionalRange?: (range: TextRange) => TextRange): CommentRange[] { return undefined; },
|
||||
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
|
||||
getTrailingComments(range: TextRange, getAdditionalRange?: (range: TextRange) => TextRange): CommentRange[] { return undefined; },
|
||||
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
|
||||
emitLeadingComments(range: TextRange, comments?: CommentRange[]): void { },
|
||||
emitTrailingComments(range: TextRange, comments?: CommentRange[]): void { },
|
||||
emitDetachedComments,
|
||||
emitLeadingComments(node: TextRange, comments?: CommentRange[]): void { },
|
||||
emitTrailingComments(node: TextRange, comments?: CommentRange[]): void { },
|
||||
};
|
||||
|
||||
function emitDetachedComments(node: TextRange): void {
|
||||
@@ -53,41 +59,85 @@ namespace ts {
|
||||
return {
|
||||
reset,
|
||||
setSourceFile,
|
||||
getLeadingCommentsToEmit,
|
||||
getTrailingCommentsToEmit,
|
||||
emitDetachedComments,
|
||||
getLeadingComments,
|
||||
getLeadingCommentsOfPosition,
|
||||
getTrailingComments,
|
||||
getTrailingCommentsOfPosition,
|
||||
emitLeadingComments,
|
||||
emitTrailingComments,
|
||||
emitDetachedComments,
|
||||
};
|
||||
|
||||
function getLeadingCommentsToEmit(node: TextRange) {
|
||||
if (nodeIsSynthesized(node)) {
|
||||
return;
|
||||
function getLeadingComments(range: TextRange | Node, getAdditionalRange?: (range: Node) => Node) {
|
||||
let comments = getLeadingCommentsOfPosition(range.pos);
|
||||
if (getAdditionalRange) {
|
||||
let additionalRange = getAdditionalRange(<Node>range);
|
||||
while (additionalRange) {
|
||||
comments = concatenate(
|
||||
getLeadingCommentsOfPosition(additionalRange.pos),
|
||||
comments
|
||||
);
|
||||
|
||||
additionalRange = getAdditionalRange(additionalRange);
|
||||
}
|
||||
}
|
||||
|
||||
if (!leadingCommentRangeNodeStarts[node.pos]) {
|
||||
leadingCommentRangeNodeStarts[node.pos] = true;
|
||||
const comments = hasDetachedComments(node.pos)
|
||||
? getLeadingCommentsWithoutDetachedComments()
|
||||
: getLeadingCommentRanges(currentText, node.pos);
|
||||
return consumeCommentRanges(comments);
|
||||
}
|
||||
|
||||
return noComments;
|
||||
return comments;
|
||||
}
|
||||
|
||||
function getTrailingCommentsToEmit(node: TextRange) {
|
||||
if (nodeIsSynthesized(node)) {
|
||||
return;
|
||||
function getTrailingComments(range: TextRange | Node, getAdditionalRange?: (range: Node) => Node) {
|
||||
let comments = getTrailingCommentsOfPosition(range.end);
|
||||
if (getAdditionalRange) {
|
||||
let additionalRange = getAdditionalRange(<Node>range);
|
||||
while (additionalRange) {
|
||||
comments = concatenate(
|
||||
comments,
|
||||
getTrailingCommentsOfPosition(additionalRange.end)
|
||||
);
|
||||
|
||||
additionalRange = getAdditionalRange(additionalRange);
|
||||
}
|
||||
}
|
||||
|
||||
if (!trailingCommentRangeNodeEnds[node.end]) {
|
||||
trailingCommentRangeNodeEnds[node.end] = true;
|
||||
const comments = getTrailingCommentRanges(currentText, node.end);
|
||||
return consumeCommentRanges(comments);
|
||||
return comments;
|
||||
}
|
||||
|
||||
function getLeadingCommentsOfPosition(pos: number) {
|
||||
if (positionIsSynthesized(pos) || leadingCommentRangePositions[pos]) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return noComments;
|
||||
leadingCommentRangePositions[pos] = true;
|
||||
const comments = hasDetachedComments(pos)
|
||||
? getLeadingCommentsWithoutDetachedComments()
|
||||
: getLeadingCommentRanges(currentText, pos);
|
||||
return consumeCommentRanges(comments);
|
||||
}
|
||||
|
||||
function getTrailingCommentsOfPosition(pos: number) {
|
||||
if (positionIsSynthesized(pos) || trailingCommentRangePositions[pos]) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
trailingCommentRangePositions[pos] = true;
|
||||
const comments = getTrailingCommentRanges(currentText, pos);
|
||||
return consumeCommentRanges(comments);
|
||||
}
|
||||
|
||||
function emitLeadingComments(range: TextRange, comments = getLeadingComments(range)) {
|
||||
emitNewLineBeforeLeadingComments(currentLineMap, writer, range, comments);
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitTrailingComments(range: TextRange, comments = getTrailingComments(range)) {
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
|
||||
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitDetachedComments(range: TextRange) {
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(range, /*removeComments*/ false);
|
||||
}
|
||||
|
||||
function hasConsumedCommentRange(comment: CommentRange) {
|
||||
@@ -136,22 +186,6 @@ namespace ts {
|
||||
|
||||
return noComments;
|
||||
}
|
||||
|
||||
function emitLeadingComments(range: TextRange, leadingComments: CommentRange[] = getLeadingCommentsToEmit(range)) {
|
||||
emitNewLineBeforeLeadingComments(currentLineMap, writer, range, leadingComments);
|
||||
|
||||
// Leading comments are emitted as `/*leading comment1 */space/*leading comment*/space`
|
||||
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitTrailingComments(range: TextRange, trailingComments = getTrailingCommentsToEmit(range)) {
|
||||
// Trailing comments are emitted as `space/*trailing comment1 */space/*trailing comment*/`
|
||||
emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitDetachedComments(range: TextRange) {
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(range, /*removeComments*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
@@ -160,8 +194,8 @@ namespace ts {
|
||||
currentLineMap = undefined;
|
||||
detachedCommentsInfo = undefined;
|
||||
consumedCommentRanges = undefined;
|
||||
trailingCommentRangeNodeEnds = undefined;
|
||||
leadingCommentRangeNodeStarts = undefined;
|
||||
trailingCommentRangePositions = undefined;
|
||||
leadingCommentRangePositions = undefined;
|
||||
}
|
||||
|
||||
function setSourceFile(sourceFile: SourceFile) {
|
||||
@@ -170,8 +204,8 @@ namespace ts {
|
||||
currentLineMap = getLineStarts(sourceFile);
|
||||
detachedCommentsInfo = undefined;
|
||||
consumedCommentRanges = [];
|
||||
leadingCommentRangeNodeStarts = [];
|
||||
trailingCommentRangeNodeEnds = [];
|
||||
leadingCommentRangePositions = [];
|
||||
trailingCommentRangePositions = [];
|
||||
}
|
||||
|
||||
function hasDetachedComments(pos: number) {
|
||||
@@ -182,7 +216,7 @@ namespace ts {
|
||||
// get the leading comments from detachedPos
|
||||
const pos = lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos;
|
||||
const leadingComments = getLeadingCommentRanges(currentText, pos);
|
||||
if (detachedCommentsInfo.length > 1) {
|
||||
if (detachedCommentsInfo.length - 1) {
|
||||
detachedCommentsInfo.pop();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ts {
|
||||
// Emit reference in dts, if the file reference was not already emitted
|
||||
if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) {
|
||||
// Add a reference to generated dts file,
|
||||
// global file reference is added only
|
||||
// global file reference is added only
|
||||
// - if it is not bundled emit (because otherwise it would be self reference)
|
||||
// - and it is not already added
|
||||
if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) {
|
||||
@@ -144,7 +144,7 @@ namespace ts {
|
||||
|
||||
if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
|
||||
// if file was external module with augmentations - this fact should be preserved in .d.ts as well.
|
||||
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
|
||||
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
|
||||
// that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
|
||||
write("export {};");
|
||||
writeLine();
|
||||
@@ -349,7 +349,7 @@ namespace ts {
|
||||
const jsDocComments = getJsDocCommentsFromText(declaration, currentText);
|
||||
emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments);
|
||||
// jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitComments(currentText, currentLineMap, writer, jsDocComments, /*trailingSeparator*/ true, newLine, writeCommentRange);
|
||||
emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeCommentRange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -736,7 +736,7 @@ namespace ts {
|
||||
|
||||
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) {
|
||||
// emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
|
||||
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
|
||||
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
|
||||
// external modules since they are indistingushable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
|
||||
// so compiler will treat them as external modules.
|
||||
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration;
|
||||
|
||||
@@ -1915,7 +1915,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
|
||||
if (multiLine) {
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
}
|
||||
|
||||
write(")");
|
||||
@@ -2242,6 +2241,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
return node;
|
||||
}
|
||||
|
||||
function skipAssertions(node: Expression): Expression {
|
||||
while (node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
|
||||
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function emitCallTarget(node: Expression): Expression {
|
||||
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword) {
|
||||
emit(node);
|
||||
@@ -3308,8 +3314,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
// we can't reuse 'arr' because it might be modified within the body of the loop.
|
||||
const counter = createTempVariable(TempFlags._i);
|
||||
const rhsReference = createSynthesizedNode(SyntaxKind.Identifier) as Identifier;
|
||||
rhsReference.text = node.expression.kind === SyntaxKind.Identifier ?
|
||||
makeUniqueName((<Identifier>node.expression).text) :
|
||||
const expressionWithoutAssertions = skipAssertions(node.expression);
|
||||
rhsReference.text = expressionWithoutAssertions.kind === SyntaxKind.Identifier ?
|
||||
makeUniqueName((<Identifier>expressionWithoutAssertions).text) :
|
||||
makeTempVariableName(TempFlags.Auto);
|
||||
|
||||
// This is the let keyword for the counter and rhsReference. The let keyword for
|
||||
@@ -4324,7 +4331,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
writeLine();
|
||||
emitStart(restParam);
|
||||
emitNodeWithCommentsAndWithoutSourcemap(restParam.name);
|
||||
write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];");
|
||||
write(restIndex > 0
|
||||
? `[${tempName} - ${restIndex}] = arguments[${tempName}];`
|
||||
: `[${tempName}] = arguments[${tempName}];`);
|
||||
emitEnd(restParam);
|
||||
decreaseIndent();
|
||||
writeLine();
|
||||
@@ -5340,6 +5349,18 @@ const _super = (function (geti, seti) {
|
||||
write(" = ");
|
||||
}
|
||||
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
|
||||
let tempVariable: Identifier;
|
||||
|
||||
if (isClassExpressionWithStaticProperties) {
|
||||
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
|
||||
write("(");
|
||||
increaseIndent();
|
||||
emit(tempVariable);
|
||||
write(" = ");
|
||||
}
|
||||
|
||||
write("(function (");
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
@@ -5369,9 +5390,6 @@ const _super = (function (geti, seti) {
|
||||
writeLine();
|
||||
emitConstructor(node, baseTypeNode);
|
||||
emitMemberFunctionsForES5AndLower(node);
|
||||
emitPropertyDeclarations(node, getInitializedProperties(node, /*isStatic*/ true));
|
||||
writeLine();
|
||||
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
|
||||
writeLine();
|
||||
emitToken(SyntaxKind.CloseBraceToken, node.members.end, () => {
|
||||
write("return ");
|
||||
@@ -5398,7 +5416,23 @@ const _super = (function (geti, seti) {
|
||||
write("))");
|
||||
if (node.kind === SyntaxKind.ClassDeclaration) {
|
||||
write(";");
|
||||
emitPropertyDeclarations(node, staticProperties);
|
||||
writeLine();
|
||||
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
|
||||
}
|
||||
else if (isClassExpressionWithStaticProperties) {
|
||||
for (const property of staticProperties) {
|
||||
write(",");
|
||||
writeLine();
|
||||
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
|
||||
}
|
||||
write(",");
|
||||
writeLine();
|
||||
emit(tempVariable);
|
||||
decreaseIndent();
|
||||
write(")");
|
||||
}
|
||||
|
||||
emitEnd(node);
|
||||
|
||||
if (node.kind === SyntaxKind.ClassDeclaration) {
|
||||
@@ -7937,7 +7971,7 @@ const _super = (function (geti, seti) {
|
||||
emitNewLineBeforeLeadingComments(currentLineMap, writer, node, leadingComments);
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
emitComments(currentText, currentLineMap, writer, leadingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitTrailingComments(node: Node) {
|
||||
@@ -7949,7 +7983,7 @@ const _super = (function (geti, seti) {
|
||||
const trailingComments = getTrailingCommentsToEmit(node);
|
||||
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
|
||||
emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ false, newLine, writeComment);
|
||||
emitComments(currentText, currentLineMap, writer, trailingComments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7964,8 +7998,8 @@ const _super = (function (geti, seti) {
|
||||
|
||||
const trailingComments = getTrailingCommentRanges(currentText, pos);
|
||||
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
|
||||
emitComments(currentText, currentLineMap, writer, trailingComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
emitComments(currentText, currentLineMap, writer, trailingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitLeadingCommentsOfPositionWorker(pos: number) {
|
||||
@@ -7986,7 +8020,7 @@ const _super = (function (geti, seti) {
|
||||
emitNewLineBeforeLeadingComments(currentLineMap, writer, { pos: pos, end: pos }, leadingComments);
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitComments(currentText, currentLineMap, writer, leadingComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
emitComments(currentText, currentLineMap, writer, leadingComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitDetachedCommentsAndUpdateCommentsInfo(node: TextRange) {
|
||||
|
||||
@@ -75,6 +75,15 @@ function __export(m) {
|
||||
}
|
||||
})`;
|
||||
|
||||
const superHelper = `
|
||||
const _super = name => super[name];`;
|
||||
|
||||
const advancedSuperHelper = `
|
||||
const _super = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`;
|
||||
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
@@ -110,20 +119,41 @@ function __export(m) {
|
||||
const transformers = getTransformers(compilerOptions).concat(initializePrinter);
|
||||
|
||||
const writer = createTextWriter(newLine);
|
||||
const { write, writeTextOfNode, writeLine, increaseIndent, decreaseIndent } = writer;
|
||||
const {
|
||||
write,
|
||||
writeTextOfNode,
|
||||
writeLine,
|
||||
increaseIndent,
|
||||
decreaseIndent
|
||||
} = writer;
|
||||
|
||||
const sourceMap = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? createSourceMapWriter(host, writer) : getNullSourceMapWriter();
|
||||
const { emitStart, emitEnd, emitPos } = sourceMap;
|
||||
const {
|
||||
emitStart,
|
||||
emitEnd,
|
||||
emitPos
|
||||
} = sourceMap;
|
||||
|
||||
const comments = createCommentWriter(host, writer, sourceMap);
|
||||
const { emitDetachedComments, emitLeadingComments, emitTrailingComments, getLeadingCommentsToEmit, getTrailingCommentsToEmit } = comments;
|
||||
const {
|
||||
getLeadingComments,
|
||||
getTrailingComments,
|
||||
getTrailingCommentsOfPosition,
|
||||
emitLeadingComments,
|
||||
emitTrailingComments,
|
||||
emitDetachedComments
|
||||
} = comments;
|
||||
|
||||
let context: TransformationContext;
|
||||
let startLexicalEnvironment: () => void;
|
||||
let endLexicalEnvironment: () => Statement[];
|
||||
let getNodeEmitFlags: (node: Node) => NodeEmitFlags;
|
||||
let isExpressionSubstitutionEnabled: (node: Node) => boolean;
|
||||
let isEmitNotificationEnabled: (node: Node) => boolean;
|
||||
let expressionSubstitution: (node: Expression) => Expression;
|
||||
let identifierSubstitution: (node: Identifier) => Identifier;
|
||||
let onBeforeEmitNode: (node: Node) => void;
|
||||
let onAfterEmitNode: (node: Node) => void;
|
||||
let isUniqueName: (name: string) => boolean;
|
||||
let temporaryVariables: string[] = [];
|
||||
let tempFlags: TempFlags;
|
||||
@@ -177,8 +207,12 @@ function __export(m) {
|
||||
startLexicalEnvironment = undefined;
|
||||
endLexicalEnvironment = undefined;
|
||||
getNodeEmitFlags = undefined;
|
||||
isExpressionSubstitutionEnabled = undefined;
|
||||
isEmitNotificationEnabled = undefined;
|
||||
expressionSubstitution = undefined;
|
||||
identifierSubstitution = undefined;
|
||||
onBeforeEmitNode = undefined;
|
||||
onAfterEmitNode = undefined;
|
||||
isUniqueName = undefined;
|
||||
temporaryVariables = undefined;
|
||||
tempFlags = 0;
|
||||
@@ -196,8 +230,12 @@ function __export(m) {
|
||||
startLexicalEnvironment = context.startLexicalEnvironment;
|
||||
endLexicalEnvironment = context.endLexicalEnvironment;
|
||||
getNodeEmitFlags = context.getNodeEmitFlags;
|
||||
isExpressionSubstitutionEnabled = context.isExpressionSubstitutionEnabled;
|
||||
isEmitNotificationEnabled = context.isEmitNotificationEnabled;
|
||||
expressionSubstitution = context.expressionSubstitution;
|
||||
identifierSubstitution = context.identifierSubstitution;
|
||||
onBeforeEmitNode = context.onBeforeEmitNode;
|
||||
onAfterEmitNode = context.onAfterEmitNode;
|
||||
isUniqueName = context.isUniqueName;
|
||||
return printSourceFile;
|
||||
}
|
||||
@@ -212,18 +250,46 @@ function __export(m) {
|
||||
}
|
||||
|
||||
function emit(node: Node) {
|
||||
emitWithWorker(node, emitWorker);
|
||||
}
|
||||
|
||||
function emitExpression(node: Expression) {
|
||||
emitWithWorker(node, emitExpressionWorker);
|
||||
}
|
||||
|
||||
function emitWithWorker(node: Node, emitWorker: (node: Node) => void) {
|
||||
if (node) {
|
||||
const leadingComments = getLeadingCommentsToEmit(node);
|
||||
const trailingComments = getTrailingCommentsToEmit(node);
|
||||
const adviseOnEmit = isEmitNotificationEnabled(node);
|
||||
if (adviseOnEmit && onBeforeEmitNode) {
|
||||
onBeforeEmitNode(node);
|
||||
}
|
||||
|
||||
const leadingComments = getLeadingComments(node, getNotEmittedParent);
|
||||
const trailingComments = getTrailingComments(node, getNotEmittedParent);
|
||||
emitLeadingComments(node, leadingComments);
|
||||
emitStart(node);
|
||||
emitWorker(node);
|
||||
emitEnd(node);
|
||||
emitTrailingComments(node, trailingComments);
|
||||
|
||||
if (adviseOnEmit && onAfterEmitNode) {
|
||||
onAfterEmitNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitWorker(node: Node) {
|
||||
function getNotEmittedParent(node: Node): Node {
|
||||
if (getNodeEmitFlags(node) & NodeEmitFlags.EmitCommentsOfNotEmittedParent) {
|
||||
const parent = getOriginalNode(node).parent;
|
||||
if (getNodeEmitFlags(parent) & NodeEmitFlags.IsNotEmittedNode) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function emitWorker(node: Node): void {
|
||||
const kind = node.kind;
|
||||
switch (kind) {
|
||||
// Pseudo-literals
|
||||
@@ -234,7 +300,11 @@ function __export(m) {
|
||||
|
||||
// Identifiers
|
||||
case SyntaxKind.Identifier:
|
||||
return emitIdentifier(<Identifier>node, identifierSubstitution);
|
||||
if (tryEmitSubstitute(node, identifierSubstitution)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return emitIdentifier(<Identifier>node);
|
||||
|
||||
// Reserved words
|
||||
case SyntaxKind.ConstKeyword:
|
||||
@@ -324,7 +394,7 @@ function __export(m) {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
||||
case SyntaxKind.ThisType:
|
||||
return write("this");
|
||||
return emitThisType(<ThisTypeNode>node);
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return emitLiteral(<StringLiteralTypeNode>node);
|
||||
|
||||
@@ -340,7 +410,7 @@ function __export(m) {
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return emitTemplateSpan(<TemplateSpan>node);
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
return write(";");
|
||||
return emitSemicolonClassElement(<SemicolonClassElement>node);
|
||||
|
||||
// Statements
|
||||
case SyntaxKind.Block:
|
||||
@@ -348,7 +418,7 @@ function __export(m) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return emitVariableStatement(<VariableStatement>node);
|
||||
case SyntaxKind.EmptyStatement:
|
||||
return write(";");
|
||||
return emitEmptyStatement(<EmptyStatement>node);
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
return emitExpressionStatement(<ExpressionStatement>node);
|
||||
case SyntaxKind.IfStatement:
|
||||
@@ -467,25 +537,17 @@ function __export(m) {
|
||||
// JSDoc nodes (ignored)
|
||||
}
|
||||
|
||||
if (isExpressionKind(kind)) {
|
||||
if (isExpression(node)) {
|
||||
return emitExpressionWorker(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitExpression(node: Expression) {
|
||||
if (node) {
|
||||
const leadingComments = getLeadingCommentsToEmit(node);
|
||||
const trailingComments = getTrailingCommentsToEmit(node);
|
||||
emitLeadingComments(node, leadingComments);
|
||||
emitStart(node);
|
||||
emitExpressionWorker(node);
|
||||
emitEnd(node);
|
||||
emitTrailingComments(node, trailingComments);
|
||||
}
|
||||
}
|
||||
|
||||
function emitExpressionWorker(node: Node) {
|
||||
const kind = node.kind;
|
||||
if (isExpressionSubstitutionEnabled(node) && tryEmitSubstitute(node, expressionSubstitution)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
// Literals
|
||||
case SyntaxKind.NumericLiteral:
|
||||
@@ -496,16 +558,15 @@ function __export(m) {
|
||||
|
||||
// Identifiers
|
||||
case SyntaxKind.Identifier:
|
||||
return emitIdentifier(<Identifier>node, expressionSubstitution);
|
||||
return emitIdentifier(<Identifier>node);
|
||||
|
||||
// Reserved words
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
return writeTokenNode(node);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return emitThisKeyword(<PrimaryExpression>node);
|
||||
return writeTokenNode(node);
|
||||
|
||||
// Expressions
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
@@ -597,17 +658,14 @@ function __export(m) {
|
||||
// Identifiers
|
||||
//
|
||||
|
||||
function emitIdentifier(node: Identifier, substitution: (node: Node) => Node) {
|
||||
if (tryEmitSubstitute(node, substitution)) {
|
||||
return;
|
||||
}
|
||||
else if (node.text === undefined) {
|
||||
function emitIdentifier(node: Identifier) {
|
||||
if (node.text === undefined) {
|
||||
// Emit a temporary variable name for this node.
|
||||
const nodeId = getOriginalNodeId(node);
|
||||
const text = temporaryVariables[nodeId] || (temporaryVariables[nodeId] = makeTempVariableName(tempKindToFlags(node.tempKind)));
|
||||
write(text);
|
||||
}
|
||||
else if (nodeIsSynthesized(node)) {
|
||||
else if (nodeIsSynthesized(node) || !node.parent) {
|
||||
if (getNodeEmitFlags(node) & NodeEmitFlags.UMDDefine) {
|
||||
writeLines(umdHelper);
|
||||
}
|
||||
@@ -620,15 +678,6 @@ function __export(m) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitThisKeyword(node: PrimaryExpression) {
|
||||
if (tryEmitSubstitute(node, expressionSubstitution)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
writeTokenNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Names
|
||||
//
|
||||
@@ -716,13 +765,13 @@ function __export(m) {
|
||||
emitModifiers(node, node.modifiers);
|
||||
writeIfPresent(node.asteriskToken, "*");
|
||||
emit(node.name);
|
||||
emitSignatureAndBody(node);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
function emitConstructor(node: ConstructorDeclaration) {
|
||||
emitModifiers(node, node.modifiers);
|
||||
write("constructor");
|
||||
emitSignatureAndBody(node);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
function emitAccessorDeclaration(node: AccessorDeclaration) {
|
||||
@@ -730,7 +779,7 @@ function __export(m) {
|
||||
emitModifiers(node, node.modifiers);
|
||||
write(node.kind === SyntaxKind.GetAccessor ? "get " : "set ");
|
||||
emit(node.name);
|
||||
emitSignatureAndBody(node);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
function emitCallSignature(node: CallSignatureDeclaration) {
|
||||
@@ -760,6 +809,10 @@ function __export(m) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitSemicolonClassElement(node: SemicolonClassElement) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
//
|
||||
// Types
|
||||
//
|
||||
@@ -826,6 +879,10 @@ function __export(m) {
|
||||
write(")");
|
||||
}
|
||||
|
||||
function emitThisType(node: ThisTypeNode) {
|
||||
write("this");
|
||||
}
|
||||
|
||||
//
|
||||
// Binding patterns
|
||||
//
|
||||
@@ -871,7 +928,7 @@ function __export(m) {
|
||||
write("[]");
|
||||
}
|
||||
else {
|
||||
const preferNewLine = getNodeEmitFlags(node) & NodeEmitFlags.MultiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
|
||||
}
|
||||
}
|
||||
@@ -882,7 +939,7 @@ function __export(m) {
|
||||
write("{}");
|
||||
}
|
||||
else {
|
||||
const preferNewLine = getNodeEmitFlags(node) & NodeEmitFlags.MultiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
}
|
||||
@@ -973,27 +1030,8 @@ function __export(m) {
|
||||
function emitArrowFunction(node: ArrowFunction) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
const body = node.body;
|
||||
if (isBlock(body)) {
|
||||
const savedTempFlags = tempFlags;
|
||||
tempFlags = 0;
|
||||
startLexicalEnvironment();
|
||||
emitArrowFunctionHead(node);
|
||||
write(" {");
|
||||
emitSignatureAndBody(node, emitArrowFunctionHead);
|
||||
|
||||
const startingLine = writer.getLine();
|
||||
emitBlockFunctionBody(node, body);
|
||||
|
||||
const endingLine = writer.getLine();
|
||||
emitLexicalEnvironment(endLexicalEnvironment(), /*newLine*/ startingLine !== endingLine);
|
||||
tempFlags = savedTempFlags;
|
||||
write("}");
|
||||
}
|
||||
else {
|
||||
emitArrowFunctionHead(node);
|
||||
write(" ");
|
||||
emitExpression(body);
|
||||
}
|
||||
}
|
||||
|
||||
function emitArrowFunctionHead(node: ArrowFunction) {
|
||||
@@ -1051,19 +1089,11 @@ function __export(m) {
|
||||
}
|
||||
|
||||
function emitPostfixUnaryExpression(node: PostfixUnaryExpression) {
|
||||
if (tryEmitSubstitute(node, expressionSubstitution)) {
|
||||
return;
|
||||
}
|
||||
|
||||
emitExpression(node.operand);
|
||||
writeToken(node.operator);
|
||||
}
|
||||
|
||||
function emitBinaryExpression(node: BinaryExpression) {
|
||||
if (tryEmitSubstitute(node, expressionSubstitution)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isCommaOperator = node.operatorToken.kind !== SyntaxKind.CommaToken;
|
||||
const indentBeforeOperator = needsIndentation(node, node.left, node.operatorToken);
|
||||
const indentAfterOperator = needsIndentation(node, node.operatorToken, node.right);
|
||||
@@ -1169,6 +1199,10 @@ function __export(m) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitEmptyStatement(node: EmptyStatement) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitExpressionStatement(node: ExpressionStatement) {
|
||||
emitExpression(node.expression);
|
||||
write(";");
|
||||
@@ -1336,25 +1370,27 @@ function __export(m) {
|
||||
emitModifiers(node, node.modifiers);
|
||||
write(node.asteriskToken ? "function* " : "function ");
|
||||
emit(node.name);
|
||||
emitSignatureAndBody(node);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
function emitSignatureAndBody(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) {
|
||||
function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) {
|
||||
const body = node.body;
|
||||
if (body) {
|
||||
const savedTempFlags = tempFlags;
|
||||
tempFlags = 0;
|
||||
startLexicalEnvironment();
|
||||
emitSignatureHead(node);
|
||||
write(" {");
|
||||
|
||||
const startingLine = writer.getLine();
|
||||
emitBlockFunctionBody(node, body);
|
||||
|
||||
const endingLine = writer.getLine();
|
||||
emitLexicalEnvironment(endLexicalEnvironment(), /*newLine*/ startingLine !== endingLine);
|
||||
write("}");
|
||||
tempFlags = savedTempFlags;
|
||||
if (isBlock(body)) {
|
||||
const savedTempFlags = tempFlags;
|
||||
tempFlags = 0;
|
||||
startLexicalEnvironment();
|
||||
emitSignatureHead(node);
|
||||
write(" {");
|
||||
emitBlockFunctionBody(node, body);
|
||||
write("}");
|
||||
tempFlags = savedTempFlags;
|
||||
}
|
||||
else {
|
||||
emitSignatureHead(node);
|
||||
write(" ");
|
||||
emitExpression(body);
|
||||
}
|
||||
}
|
||||
else {
|
||||
emitSignatureHead(node);
|
||||
@@ -1371,34 +1407,49 @@ function __export(m) {
|
||||
|
||||
function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) {
|
||||
const originalNode = getOriginalNode(parentNode);
|
||||
if (isFunctionLike(originalNode) && !nodeIsSynthesized(originalNode) && rangeEndIsOnSameLineAsRangeStart(originalNode.body, originalNode.body)) {
|
||||
for (const statement of body.statements) {
|
||||
if (synthesizedNodeStartsOnNewLine(statement)) {
|
||||
return false;
|
||||
if (isFunctionLike(originalNode) && !nodeIsSynthesized(originalNode)) {
|
||||
const body = originalNode.body;
|
||||
if (isBlock(body)) {
|
||||
if (rangeEndIsOnSameLineAsRangeStart(body, body)) {
|
||||
for (const statement of body.statements) {
|
||||
if (synthesizedNodeStartsOnNewLine(statement)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (originalNode.kind === SyntaxKind.ArrowFunction && !rangeEndIsOnSameLineAsRangeStart((<ArrowFunction>originalNode).equalsGreaterThanToken, originalNode.body)) {
|
||||
return false;
|
||||
else {
|
||||
return rangeEndIsOnSameLineAsRangeStart((<ArrowFunction>originalNode).equalsGreaterThanToken, originalNode.body);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function emitBlockFunctionBody(parentNode: Node, body: Block) {
|
||||
const startingLine = writer.getLine();
|
||||
increaseIndent();
|
||||
emitDetachedComments(body.statements);
|
||||
|
||||
// Emit all the prologue directives (like "use strict").
|
||||
const statements = body.statements;
|
||||
const statementOffset = emitPrologueDirectives(statements, /*startWithNewLine*/ true, /*indented*/ true);
|
||||
const statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true);
|
||||
const helpersEmitted = emitHelpers(body);
|
||||
|
||||
if (statementOffset === 0 && !helpersEmitted && shouldEmitBlockFunctionBodyOnSingleLine(parentNode, body)) {
|
||||
emitList(body, statements, ListFormat.SingleLineFunctionBodyStatements);
|
||||
decreaseIndent();
|
||||
emitList(body, body.statements, ListFormat.SingleLineFunctionBodyStatements);
|
||||
increaseIndent();
|
||||
}
|
||||
else {
|
||||
emitList(body, statements, ListFormat.MultiLineFunctionBodyStatements, statementOffset);
|
||||
emitList(body, body.statements, ListFormat.MultiLineFunctionBodyStatements, statementOffset);
|
||||
}
|
||||
|
||||
const endingLine = writer.getLine();
|
||||
emitLexicalEnvironment(endLexicalEnvironment(), /*newLine*/ startingLine !== endingLine);
|
||||
emitLeadingComments(collapseTextRange(body.statements, TextRangeCollapse.CollapseToEnd));
|
||||
decreaseIndent();
|
||||
}
|
||||
|
||||
function emitClassDeclaration(node: ClassDeclaration) {
|
||||
@@ -1668,6 +1719,8 @@ function __export(m) {
|
||||
write("case ");
|
||||
emitExpression(node.expression);
|
||||
write(":");
|
||||
|
||||
debugger;
|
||||
emitCaseOrDefaultClauseStatements(node, node.statements);
|
||||
}
|
||||
|
||||
@@ -1688,6 +1741,7 @@ function __export(m) {
|
||||
|
||||
function emitHeritageClause(node: HeritageClause) {
|
||||
emitStart(node);
|
||||
write(" ");
|
||||
writeToken(node.token);
|
||||
write(" ");
|
||||
emitList(node, node.types, ListFormat.HeritageClauseTypes);
|
||||
@@ -1783,8 +1837,7 @@ function __export(m) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, indented?: boolean) {
|
||||
increaseIndentIf(indented);
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean) {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
if (isPrologueDirective(statements[i])) {
|
||||
if (startWithNewLine || i > 0) {
|
||||
@@ -1794,12 +1847,10 @@ function __export(m) {
|
||||
}
|
||||
else {
|
||||
// return index of the first non prologue directive
|
||||
decreaseIndentIf(indented);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
decreaseIndentIf(indented);
|
||||
return statements.length;
|
||||
}
|
||||
|
||||
@@ -1811,7 +1862,17 @@ function __export(m) {
|
||||
}
|
||||
|
||||
if (emitFlags & NodeEmitFlags.EmitExportStar) {
|
||||
emitExportStarHelper();
|
||||
writeLines(exportStarHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (emitFlags & NodeEmitFlags.EmitSuperHelper) {
|
||||
writeLines(superHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (emitFlags & NodeEmitFlags.EmitAdvancedSuperHelper) {
|
||||
writeLines(advancedSuperHelper);
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
@@ -1861,10 +1922,6 @@ function __export(m) {
|
||||
return helpersEmitted;
|
||||
}
|
||||
|
||||
function emitExportStarHelper() {
|
||||
writeLines(exportStarHelper);
|
||||
}
|
||||
|
||||
function writeLines(text: string): void {
|
||||
const lines = text.split(/\r\n|\r|\n/g);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
@@ -2027,8 +2084,10 @@ function __export(m) {
|
||||
}
|
||||
else {
|
||||
// Write the opening line terminator or leading whitespace.
|
||||
let shouldEmitInterveningComments = true;
|
||||
if (shouldWriteLeadingLineTerminator(parentNode, children, format)) {
|
||||
writeLine();
|
||||
shouldEmitInterveningComments = false;
|
||||
}
|
||||
else if (format & ListFormat.SpaceBetweenBraces) {
|
||||
write(" ");
|
||||
@@ -2052,12 +2111,20 @@ function __export(m) {
|
||||
// Write either a line terminator or whitespace to separate the elements.
|
||||
if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
|
||||
writeLine();
|
||||
shouldEmitInterveningComments = false;
|
||||
}
|
||||
else if (previousSibling) {
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldEmitInterveningComments) {
|
||||
emitLeadingComments(child, getTrailingCommentsOfPosition(child.pos));
|
||||
}
|
||||
else {
|
||||
shouldEmitInterveningComments = true;
|
||||
}
|
||||
|
||||
// Emit this child.
|
||||
emit(child);
|
||||
|
||||
@@ -2151,7 +2218,7 @@ function __export(m) {
|
||||
return true;
|
||||
}
|
||||
else if (format & ListFormat.PreserveLines) {
|
||||
if (getNodeEmitFlags(parentNode) & NodeEmitFlags.MultiLine) {
|
||||
if (format & ListFormat.PreferNewLine) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2193,10 +2260,10 @@ function __export(m) {
|
||||
|
||||
function shouldWriteClosingLineTerminator(parentNode: Node, children: NodeArray<Node>, format: ListFormat) {
|
||||
if (format & ListFormat.MultiLine) {
|
||||
return true;
|
||||
return (format & ListFormat.NoTrailingNewLine) === 0;
|
||||
}
|
||||
else if (format & ListFormat.PreserveLines) {
|
||||
if (getNodeEmitFlags(parentNode) & NodeEmitFlags.MultiLine) {
|
||||
if (format & ListFormat.PreferNewLine) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2218,7 +2285,7 @@ function __export(m) {
|
||||
|
||||
function synthesizedNodeStartsOnNewLine(node: Node, format?: ListFormat) {
|
||||
if (nodeIsSynthesized(node)) {
|
||||
const startsOnNewLine = (<SynthesizedNode>node).startsOnNewLine;
|
||||
const startsOnNewLine = node.startsOnNewLine;
|
||||
if (startsOnNewLine === undefined) {
|
||||
return (format & ListFormat.PreferNewLine) !== 0;
|
||||
}
|
||||
@@ -2250,8 +2317,12 @@ function __export(m) {
|
||||
}
|
||||
|
||||
function needsIndentation(parent: Node, node1: Node, node2: Node): boolean {
|
||||
parent = skipSynthesizedParentheses(parent);
|
||||
node1 = skipSynthesizedParentheses(node1);
|
||||
node2 = skipSynthesizedParentheses(node2);
|
||||
|
||||
// Always use a newline for synthesized code if the synthesizer desires it.
|
||||
if (synthesizedNodeStartsOnNewLine(node2)) {
|
||||
if (node2.startsOnNewLine) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2261,6 +2332,14 @@ function __export(m) {
|
||||
&& !rangeEndIsOnSameLineAsRangeStart(node1, node2);
|
||||
}
|
||||
|
||||
function skipSynthesizedParentheses(node: Node) {
|
||||
while (node.kind === SyntaxKind.ParenthesizedExpression && nodeIsSynthesized(node)) {
|
||||
node = (<ParenthesizedExpression>node).expression;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function getTextOfNode(node: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(node) && (isLiteralExpression(node) || isIdentifier(node))) {
|
||||
return node.text;
|
||||
@@ -2280,9 +2359,9 @@ function __export(m) {
|
||||
}
|
||||
|
||||
function isSingleLineEmptyBlock(block: Block) {
|
||||
return (getNodeEmitFlags(block) & NodeEmitFlags.MultiLine) === 0 &&
|
||||
block.statements.length === 0 &&
|
||||
rangeEndIsOnSameLineAsRangeStart(block, block);
|
||||
return !block.multiLine
|
||||
&& block.statements.length === 0
|
||||
&& rangeEndIsOnSameLineAsRangeStart(block, block);
|
||||
}
|
||||
|
||||
function tempKindToFlags(kind: TempVariableKind) {
|
||||
@@ -2383,6 +2462,7 @@ function __export(m) {
|
||||
|
||||
// Other
|
||||
PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes.
|
||||
NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
|
||||
// Precomputed Formats
|
||||
TypeLiteralMembers = MultiLine | Indented,
|
||||
@@ -2400,7 +2480,7 @@ function __export(m) {
|
||||
MultiLineBlockStatements = Indented | MultiLine,
|
||||
VariableDeclarationList = CommaDelimited | SingleLine,
|
||||
SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenBraces,
|
||||
MultiLineFunctionBodyStatements = MultiLine | Indented,
|
||||
MultiLineFunctionBodyStatements = MultiLine,
|
||||
ClassHeritageClauses = SingleLine,
|
||||
ClassMembers = Indented | MultiLine,
|
||||
InterfaceMembers = Indented | MultiLine,
|
||||
@@ -2409,9 +2489,9 @@ function __export(m) {
|
||||
NamedImportsOrExportsElements = CommaDelimited | AllowTrailingComma | SingleLine | SpaceBetweenBraces,
|
||||
JsxElementChildren = SingleLine,
|
||||
JsxElementAttributes = SingleLine,
|
||||
CaseOrDefaultClauseStatements = Indented | MultiLine,
|
||||
CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty,
|
||||
HeritageClauseTypes = CommaDelimited | SingleLine,
|
||||
SourceFileStatements = MultiLine,
|
||||
SourceFileStatements = MultiLine | NoTrailingNewLine,
|
||||
Decorators = MultiLine | Optional,
|
||||
TypeArguments = CommaDelimited | SingleLine | Indented | AngleBrackets | Optional,
|
||||
TypeParameters = CommaDelimited | SingleLine | Indented | AngleBrackets | Optional,
|
||||
|
||||
@@ -968,7 +968,8 @@ namespace ts {
|
||||
|
||||
const start = new Date().getTime();
|
||||
|
||||
const emitResult = emitFiles(
|
||||
const fileEmitter = options.experimentalTransforms ? printFiles : emitFiles;
|
||||
const emitResult = fileEmitter(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile);
|
||||
|
||||
@@ -7,12 +7,15 @@ namespace ts {
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
emitPos(pos: number): void;
|
||||
emitStart(range: TextRange): void;
|
||||
emitEnd(range: TextRange, stopOverridingSpan?: boolean): void;
|
||||
changeEmitSourcePos(): void;
|
||||
emitEnd(range: TextRange): void;
|
||||
/*@deprecated*/ emitEnd(range: TextRange, stopOverridingSpan: boolean): void;
|
||||
/*@deprecated*/ changeEmitSourcePos(): void;
|
||||
getText(): string;
|
||||
getSourceMappingURL(): string;
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
|
||||
reset(): void;
|
||||
enable(): void;
|
||||
disable(): void;
|
||||
}
|
||||
|
||||
let nullSourceMapWriter: SourceMapWriter;
|
||||
@@ -38,6 +41,8 @@ namespace ts {
|
||||
getSourceMappingURL(): string { return undefined; },
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void { },
|
||||
reset(): void { },
|
||||
enable(): void { },
|
||||
disable(): void { }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,6 +67,8 @@ namespace ts {
|
||||
// Source map data
|
||||
let sourceMapData: SourceMapData;
|
||||
|
||||
let disableDepth: number;
|
||||
|
||||
return {
|
||||
getSourceMapData: () => sourceMapData,
|
||||
setSourceFile,
|
||||
@@ -73,6 +80,8 @@ namespace ts {
|
||||
getSourceMappingURL,
|
||||
initialize,
|
||||
reset,
|
||||
enable,
|
||||
disable,
|
||||
};
|
||||
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
@@ -81,6 +90,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
currentSourceFile = undefined;
|
||||
disableDepth = 0;
|
||||
|
||||
// Current source map file and its index in the sources list
|
||||
sourceMapSourceIndex = -1;
|
||||
@@ -147,6 +157,17 @@ namespace ts {
|
||||
lastEncodedSourceMapSpan = undefined;
|
||||
lastEncodedNameIndex = undefined;
|
||||
sourceMapData = undefined;
|
||||
disableDepth = 0;
|
||||
}
|
||||
|
||||
function enable() {
|
||||
if (disableDepth > 0) {
|
||||
disableDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
function disable() {
|
||||
disableDepth++;
|
||||
}
|
||||
|
||||
function updateLastEncodedAndRecordedSpans() {
|
||||
@@ -168,7 +189,7 @@ namespace ts {
|
||||
sourceMapData.sourceMapDecodedMappings[sourceMapData.sourceMapDecodedMappings.length - 1] :
|
||||
defaultLastEncodedSourceMapSpan;
|
||||
|
||||
// TODO: Update lastEncodedNameIndex
|
||||
// TODO: Update lastEncodedNameIndex
|
||||
// Since we dont support this any more, lets not worry about it right now.
|
||||
// When we start supporting nameIndex, we will get back to this
|
||||
|
||||
@@ -236,7 +257,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitPos(pos: number) {
|
||||
if (pos === -1) {
|
||||
if (positionIsSynthesized(pos) || disableDepth > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -288,9 +309,17 @@ namespace ts {
|
||||
|
||||
function emitStart(range: TextRange) {
|
||||
emitPos(getStartPos(range));
|
||||
|
||||
if (range.disableSourceMap) {
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
function emitEnd(range: TextRange, stopOverridingEnd?: boolean) {
|
||||
if (range.disableSourceMap) {
|
||||
enable();
|
||||
}
|
||||
|
||||
emitPos(range.end);
|
||||
stopOverridingSpan = stopOverridingEnd;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace ts {
|
||||
export interface TextRange {
|
||||
pos: number;
|
||||
end: number;
|
||||
/* @internal */ disableSourceMap?: boolean; // Whether a synthesized text range disables source maps for its contents (used by transforms).
|
||||
}
|
||||
|
||||
// token > SyntaxKind.Identifer => token is a keyword
|
||||
@@ -2468,6 +2469,7 @@ namespace ts {
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
allowJs?: boolean;
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
/* @internal */ experimentalTransforms?: boolean;
|
||||
|
||||
// Skip checking lib.d.ts to help speed up tests.
|
||||
/* @internal */ skipDefaultLibCheck?: boolean;
|
||||
@@ -2793,14 +2795,16 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export const enum NodeEmitFlags {
|
||||
EmitEmitHelpers = 1 << 0, // Any emit helpers should be written to this node.
|
||||
EmitExportStar = 1 << 1, // The export * helper should be written to this node.
|
||||
EmitSuperHelper = 1 << 2, // Emit the basic _super helper for async methods.
|
||||
EmitAdvancedSuperHelper = 1 << 3, // Emit the advanced _super helper for async methods.
|
||||
UMDDefine = 1 << 4, // This node should be replaced with the UMD define helper.
|
||||
NoLexicalEnvironment = 1 << 5, // A new LexicalEnvironment should *not* be introduced when emitting this node, this is primarily used when printing a SystemJS module.
|
||||
SingleLine = 1 << 6, // The contents of this node should be emit on a single line.
|
||||
AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node.
|
||||
EmitEmitHelpers = 1 << 0, // Any emit helpers should be written to this node.
|
||||
EmitExportStar = 1 << 1, // The export * helper should be written to this node.
|
||||
EmitSuperHelper = 1 << 2, // Emit the basic _super helper for async methods.
|
||||
EmitAdvancedSuperHelper = 1 << 3, // Emit the advanced _super helper for async methods.
|
||||
UMDDefine = 1 << 4, // This node should be replaced with the UMD define helper.
|
||||
NoLexicalEnvironment = 1 << 5, // A new LexicalEnvironment should *not* be introduced when emitting this node, this is primarily used when printing a SystemJS module.
|
||||
SingleLine = 1 << 6, // The contents of this node should be emit on a single line.
|
||||
AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node.
|
||||
IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible.
|
||||
EmitCommentsOfNotEmittedParent = 1 << 8, // Emits comments of missing parent nodes.
|
||||
}
|
||||
|
||||
/** Additional context provided to `visitEachChild` */
|
||||
|
||||
@@ -2290,26 +2290,33 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function emitComments(text: string, lineMap: number[], writer: EmitTextWriter, comments: CommentRange[], trailingSeparator: boolean, newLine: string,
|
||||
export function emitComments(text: string, lineMap: number[], writer: EmitTextWriter, comments: CommentRange[], leadingSeparator: boolean, trailingSeparator: boolean, newLine: string,
|
||||
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, comment: CommentRange, newLine: string) => void) {
|
||||
let emitLeadingSpace = !trailingSeparator;
|
||||
forEach(comments, comment => {
|
||||
if (emitLeadingSpace) {
|
||||
writer.write(" ");
|
||||
emitLeadingSpace = false;
|
||||
}
|
||||
writeComment(text, lineMap, writer, comment, newLine);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else if (trailingSeparator) {
|
||||
if (comments && comments.length > 0) {
|
||||
if (leadingSeparator) {
|
||||
writer.write(" ");
|
||||
}
|
||||
else {
|
||||
// Emit leading space to separate comment during next comment emit
|
||||
emitLeadingSpace = true;
|
||||
|
||||
let emitInterveningSeperator = false;
|
||||
for (const comment of comments) {
|
||||
if (emitInterveningSeperator) {
|
||||
writer.write(" ");
|
||||
emitInterveningSeperator = false;
|
||||
}
|
||||
|
||||
writeComment(text, lineMap, writer, comment, newLine);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
emitInterveningSeperator = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (emitInterveningSeperator && trailingSeparator) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2366,7 +2373,7 @@ namespace ts {
|
||||
if (nodeLine >= lastCommentLine + 2) {
|
||||
// Valid detachedComments
|
||||
emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
|
||||
emitComments(text, lineMap, writer, detachedComments, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
||||
}
|
||||
}
|
||||
@@ -2705,6 +2712,21 @@ namespace ts {
|
||||
return carriageReturnLineFeed;
|
||||
}
|
||||
|
||||
export const enum TextRangeCollapse {
|
||||
CollapseToStart,
|
||||
CollapseToEnd,
|
||||
}
|
||||
|
||||
export function collapseTextRange(range: TextRange, collapse: TextRangeCollapse) {
|
||||
if (range.pos === range.end) {
|
||||
return range;
|
||||
}
|
||||
|
||||
return collapse === TextRangeCollapse.CollapseToStart
|
||||
? { pos: range.pos, end: range.end }
|
||||
: { pos: range.end, end: range.end };
|
||||
}
|
||||
|
||||
// Node tests
|
||||
//
|
||||
// All node tests in the following list should *not* reference parent pointers so that
|
||||
|
||||
Reference in New Issue
Block a user