Skip to content

Commit 9889c21

Browse files
alexeaglerobertmesserle
authored andcommitted
fix(metadata): emit metadata rooted at 'angular2'
fixes #8144 closes #8147
1 parent e69cb40 commit 9889c21

File tree

2 files changed

+48
-29
lines changed

2 files changed

+48
-29
lines changed

tools/broccoli/broccoli-typescript.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,16 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
8888
this.tsServiceHost = new CustomLanguageServiceHost(this.tsOpts, this.rootFilePaths,
8989
this.fileRegistry, this.inputPath);
9090
this.tsService = ts.createLanguageService(this.tsServiceHost, ts.createDocumentRegistry());
91-
this.metadataCollector = new MetadataCollector();
91+
this.metadataCollector = new MetadataCollector({
92+
// Since our code isn't under a node_modules directory, we need to reverse the module
93+
// resolution to get metadata rooted at 'angular2'.
94+
// see https://github.com/angular/angular/issues/8144
95+
reverseModuleResolution(fileName: string) {
96+
if (/\.tmp\/angular2/.test(fileName)) {
97+
return fileName.substr(fileName.lastIndexOf('.tmp/angular2/') + 5).replace(/\.ts$/, '');
98+
}
99+
}
100+
});
92101
}
93102

94103

tools/metadata/src/collector.ts

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,49 @@ function pathTo(from: string, to: string): string {
2727
return result;
2828
}
2929

30-
function moduleNameFromBaseName(moduleFileName: string, baseFileName: string): string {
31-
// Remove the extension
32-
moduleFileName = moduleFileName.replace(EXT_REGEX, '');
33-
34-
// Check for node_modules
35-
const nodeModulesIndex = moduleFileName.lastIndexOf(NODE_MODULES);
36-
if (nodeModulesIndex >= 0) {
37-
return moduleFileName.substr(nodeModulesIndex + NODE_MODULES.length);
38-
}
39-
if (moduleFileName.lastIndexOf(NODE_MODULES_PREFIX, NODE_MODULES_PREFIX.length) !== -1) {
40-
return moduleFileName.substr(NODE_MODULES_PREFIX.length);
41-
}
42-
43-
// Construct a simplified path from the file to the module
44-
return pathTo(baseFileName, moduleFileName);
30+
export interface MetadataCollectorHost {
31+
reverseModuleResolution: (moduleFileName: string) => string;
4532
}
4633

34+
const nodeModuleResolutionHost: MetadataCollectorHost = {
35+
// Reverse moduleResolution=node for packages resolved in node_modules
36+
reverseModuleResolution(fileName: string) {
37+
// Remove the extension
38+
const moduleFileName = fileName.replace(EXT_REGEX, '');
39+
// Check for node_modules
40+
const nodeModulesIndex = moduleFileName.lastIndexOf(NODE_MODULES);
41+
if (nodeModulesIndex >= 0) {
42+
return moduleFileName.substr(nodeModulesIndex + NODE_MODULES.length);
43+
}
44+
if (moduleFileName.lastIndexOf(NODE_MODULES_PREFIX, NODE_MODULES_PREFIX.length) !== -1) {
45+
return moduleFileName.substr(NODE_MODULES_PREFIX.length);
46+
}
47+
return null;
48+
}
49+
};
50+
4751
/**
4852
* Collect decorator metadata from a TypeScript module.
4953
*/
5054
export class MetadataCollector {
51-
constructor() {}
55+
constructor(private host: MetadataCollectorHost = nodeModuleResolutionHost) {}
5256

5357
/**
5458
* Returns a JSON.stringify friendly form describing the decorators of the exported classes from
5559
* the source file that is expected to correspond to a module.
5660
*/
5761
public getMetadata(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker): ModuleMetadata {
5862
const locals = new Symbols();
59-
const moduleNameOf = (fileName: string) =>
60-
moduleNameFromBaseName(fileName, sourceFile.fileName);
63+
const moduleNameOf = (fileName: string) => {
64+
// If the module was resolved with TS moduleResolution, reverse that mapping
65+
const hostResolved = this.host.reverseModuleResolution(fileName);
66+
if (hostResolved) {
67+
return hostResolved;
68+
}
69+
// Construct a simplified path from the file to the module
70+
return pathTo(sourceFile.fileName, fileName).replace(EXT_REGEX, '');
71+
};
72+
6173
const evaluator = new Evaluator(typeChecker, locals, moduleNameOf);
6274

6375
function objFromDecorator(decoratorNode: ts.Decorator): MetadataSymbolicExpression {
@@ -85,15 +97,13 @@ export class MetadataCollector {
8597
}
8698

8799
function classMetadataOf(classDeclaration: ts.ClassDeclaration): ClassMetadata {
88-
let result: ClassMetadata =
89-
{ __symbolic: "class" }
90-
91-
function getDecorators(decorators: ts.Decorator[]):
92-
MetadataSymbolicExpression[] {
93-
if (decorators && decorators.length)
94-
return decorators.map(decorator => objFromDecorator(decorator));
95-
return undefined;
96-
}
100+
let result: ClassMetadata = {__symbolic: "class"};
101+
102+
function getDecorators(decorators: ts.Decorator[]): MetadataSymbolicExpression[] {
103+
if (decorators && decorators.length)
104+
return decorators.map(decorator => objFromDecorator(decorator));
105+
return undefined;
106+
}
97107

98108
// Add class decorators
99109
if (classDeclaration.decorators) {
@@ -175,7 +185,7 @@ export class MetadataCollector {
175185
const classDeclaration = <ts.ClassDeclaration>declaration;
176186
if (classDeclaration.decorators) {
177187
if (!metadata) metadata = {};
178-
metadata[classDeclaration.name.text] = classMetadataOf(classDeclaration)
188+
metadata[classDeclaration.name.text] = classMetadataOf(classDeclaration);
179189
}
180190
break;
181191
case ts.SyntaxKind.VariableDeclaration:

0 commit comments

Comments
 (0)