Support synthesized SourceFile parent in getOrCreateEmitNode (#24709)

getOrCreateEmitNode() assumes that the SourceFile of node that is
part of a parse tree will also be a parse tree node. This assumption is
not valid for a transformed SourceFile. disposeEmitNodes() already handles
this case by getting the original SourceFile node if the provided node
is synthesized, so do the same in getOrCreateEmitNode().

This results in the test case in #24709 to run without error.
This commit is contained in:
ispedals
2018-10-28 12:38:16 -04:00
parent e2100cd2cc
commit 57546393ff
3 changed files with 47 additions and 1 deletions

View File

@@ -2819,7 +2819,7 @@ namespace ts {
return node.emitNode = { annotatedNodes: [node] } as EmitNode;
}
const sourceFile = getSourceFileOfNode(node);
const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node)));
getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node);
}

View File

@@ -400,6 +400,46 @@ namespace Foo {
}
}).outputText;
});
// https://github.com/Microsoft/TypeScript/issues/24709
testBaseline("issue24709", () => {
const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true);
const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]);
const transformedSourceFile = transformed.transformed[0];
transformed.dispose();
const host = new fakes.CompilerHost(fs);
host.getSourceFile = () => transformedSourceFile;
const program = createProgram(["source.ts"], {
target: ScriptTarget.ES3,
module: ModuleKind.None,
noLib: true
}, host);
program.emit(transformedSourceFile, (_p, s, b) => host.writeFile("source.js", s, b));
return host.readFile("source.js")!.toString();
function transformSourceFile(context: TransformationContext) {
const visitor: Visitor = (node) => {
if (isMethodDeclaration(node)) {
return updateMethod(
node,
node.decorators,
node.modifiers,
node.asteriskToken,
createIdentifier("foobar"),
node.questionToken,
node.typeParameters,
node.parameters,
node.type,
node.body,
);
}
return visitEachChild(node, visitor, context);
};
return (node: SourceFile) => visitNode(node, visitor);
}
});
});
}

View File

@@ -0,0 +1,6 @@
var X = /** @class */ (function () {
function X() {
}
X.prototype.foobar = function (x) { return x; };
return X;
}());