Skip to content

Commit bdfb92a

Browse files
committed
Fix crash in name resolution with custom transforms and emitDecoratorMetadata
1 parent 4c68b6d commit bdfb92a

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23508,6 +23508,15 @@ namespace ts {
2350823508
}
2350923509

2351023510
function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
23511+
// ensure both `typeName` and `location` are parse tree nodes.
23512+
typeName = getParseTreeNode(typeName, isEntityName);
23513+
if (!typeName) return TypeReferenceSerializationKind.Unknown;
23514+
23515+
if (location) {
23516+
location = getParseTreeNode(location);
23517+
if (!location) return TypeReferenceSerializationKind.Unknown;
23518+
}
23519+
2351123520
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
2351223521
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
2351323522

src/compiler/transformers/ts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1944,7 +1944,7 @@ namespace ts {
19441944
const name = getMutableClone(<Identifier>node);
19451945
name.flags &= ~NodeFlags.Synthesized;
19461946
name.original = undefined;
1947-
name.parent = currentScope;
1947+
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
19481948
if (useFallback) {
19491949
return createLogicalAnd(
19501950
createStrictInequality(

src/harness/unittests/customTransforms.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33

44
namespace ts {
55
describe("customTransforms", () => {
6-
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
6+
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) {
77
it(name, () => {
88
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
99
const fileMap = arrayToMap(roots, file => file.fileName);
1010
const outputs = createMap<string>();
11-
const options: CompilerOptions = {};
1211
const host: CompilerHost = {
1312
getSourceFile: (fileName) => fileMap.get(fileName),
1413
getDefaultLibFileName: () => "lib.d.ts",
@@ -82,5 +81,25 @@ namespace ts {
8281
emitsCorrectly("before", sources, { before: [before] });
8382
emitsCorrectly("after", sources, { after: [after] });
8483
emitsCorrectly("both", sources, { before: [before], after: [after] });
84+
85+
emitsCorrectly("before+decorators", [{
86+
file: "source.ts",
87+
text: `
88+
declare const dec: any;
89+
class B {}
90+
@dec export class C { constructor(b: B) { } }
91+
'change'
92+
`
93+
}], {before: [
94+
context => node => visitNode(node, function visitor(node: Node): Node {
95+
if (isStringLiteral(node) && node.text === "change") return createLiteral("changed");
96+
return visitEachChild(node, visitor, context);
97+
})
98+
]}, {
99+
target: ScriptTarget.ES5,
100+
module: ModuleKind.ES2015,
101+
emitDecoratorMetadata: true,
102+
experimentalDecorators: true
103+
});
85104
});
86105
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// [source.js]
2+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6+
return c > 3 && r && Object.defineProperty(target, key, r), r;
7+
};
8+
var __metadata = (this && this.__metadata) || function (k, v) {
9+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10+
};
11+
var B = /** @class */ (function () {
12+
function B() {
13+
}
14+
return B;
15+
}());
16+
var C = /** @class */ (function () {
17+
function C(b) {
18+
}
19+
C = __decorate([
20+
dec,
21+
__metadata("design:paramtypes", [B])
22+
], C);
23+
return C;
24+
}());
25+
export { C };
26+
"changed";

0 commit comments

Comments
 (0)