Fix crash in name resolution with custom transforms and emitDecoratorMetadata

This commit is contained in:
Ron Buckton
2017-08-25 14:17:48 -07:00
parent 62678cd736
commit 187a21cbac
4 changed files with 57 additions and 3 deletions

View File

@@ -23454,6 +23454,15 @@ namespace ts {
}
function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
// ensure both `typeName` and `location` are parse tree nodes.
typeName = getParseTreeNode(typeName, isEntityName);
if (!typeName) return TypeReferenceSerializationKind.Unknown;
if (location) {
location = getParseTreeNode(location);
if (!location) return TypeReferenceSerializationKind.Unknown;
}
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);

View File

@@ -1947,7 +1947,7 @@ namespace ts {
const name = getMutableClone(<Identifier>node);
name.flags &= ~NodeFlags.Synthesized;
name.original = undefined;
name.parent = currentScope;
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
if (useFallback) {
return createLogicalAnd(
createStrictInequality(

View File

@@ -3,12 +3,11 @@
namespace ts {
describe("customTransforms", () => {
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) {
it(name, () => {
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
const fileMap = arrayToMap(roots, file => file.fileName);
const outputs = createMap<string>();
const options: CompilerOptions = {};
const host: CompilerHost = {
getSourceFile: (fileName) => fileMap.get(fileName),
getDefaultLibFileName: () => "lib.d.ts",
@@ -82,5 +81,25 @@ namespace ts {
emitsCorrectly("before", sources, { before: [before] });
emitsCorrectly("after", sources, { after: [after] });
emitsCorrectly("both", sources, { before: [before], after: [after] });
emitsCorrectly("before+decorators", [{
file: "source.ts",
text: `
declare const dec: any;
class B {}
@dec export class C { constructor(b: B) { } }
'change'
`
}], {before: [
context => node => visitNode(node, function visitor(node: Node): Node {
if (isStringLiteral(node) && node.text === "change") return createLiteral("changed");
return visitEachChild(node, visitor, context);
})
]}, {
target: ScriptTarget.ES5,
module: ModuleKind.ES2015,
emitDecoratorMetadata: true,
experimentalDecorators: true
});
});
}