Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23508,6 +23508,15 @@ namespace ts {
}

function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
// ensure both `typeName` and `location` are parse tree nodes.
typeName = getParseTreeNode(typeName, isEntityName);

@weswigham Wesley Wigham (weswigham) Aug 25, 2017 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems needlessly conservative - resolveEntityName does not use parent pointers on the name argument if location is present - it just draws the names to lookup from it. I don't think it strictly needs to be a parse tree node (and more importantly, couldn't a transform morph one name into another? Shouldn't that be resolved, so the serialized kind also reflects the transformation?)?

Probably too much of an edge case to care about until someone asks for it, anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather guard against it in any event.

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
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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";