Skip to content

Commit

Permalink
Fix crash in name resolution with custom transforms and emitDecorator…
Browse files Browse the repository at this point in the history
…Metadata
  • Loading branch information
rbuckton committed Aug 25, 2017
1 parent 62678cd commit 187a21c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/compiler/checker.ts
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transformers/ts.ts
Expand Up @@ -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(
Expand Down
23 changes: 21 additions & 2 deletions src/harness/unittests/customTransforms.ts
Expand Up @@ -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",
Expand Down Expand Up @@ -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
});
});
}
26 changes: 26 additions & 0 deletions tests/baselines/reference/customTransforms/before+decorators.js
@@ -0,0 +1,26 @@
// [source.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var B = /** @class */ (function () {
function B() {
}
return B;
}());
var C = /** @class */ (function () {
function C(b) {
}
C = __decorate([
dec,
__metadata("design:paramtypes", [B])
], C);
return C;
}());
export { C };
"changed";

0 comments on commit 187a21c

Please sign in to comment.