@angular/compiler-cli
Advanced tools
Comparing version 0.4.1 to 0.5.0
{ | ||
"name": "@angular/compiler-cli", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "Execute angular2 template compiler in nodejs.", | ||
@@ -19,5 +19,5 @@ "main": "index.js", | ||
"typescript": "^1.9.0-dev", | ||
"@angular/compiler": "^2.0.0-rc.4", | ||
"@angular/platform-server": "^2.0.0-rc.4", | ||
"@angular/core": "^2.0.0-rc.4" | ||
"@angular/compiler": "^2.0.0-rc.5", | ||
"@angular/platform-server": "^2.0.0-rc.5", | ||
"@angular/core": "^2.0.0-rc.5" | ||
}, | ||
@@ -40,3 +40,3 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/angular/angular/tree/master/tools/compiler-cli" | ||
"homepage": "https://github.com/angular/angular/tree/master/modules/@angular/compiler-cli" | ||
} |
@@ -15,3 +15,2 @@ /** | ||
import * as ts from 'typescript'; | ||
import { CompileMetadataResolver } from './compiler_private'; | ||
import { ReflectorHost, ReflectorHostContext } from './reflector_host'; | ||
@@ -24,8 +23,6 @@ import { StaticReflector } from './static_reflector'; | ||
private staticReflector; | ||
private resolver; | ||
private compiler; | ||
private reflectorHost; | ||
constructor(options: AngularCompilerOptions, program: ts.Program, host: ts.CompilerHost, staticReflector: StaticReflector, resolver: CompileMetadataResolver, compiler: compiler.OfflineCompiler, reflectorHost: ReflectorHost); | ||
private generateSource(metadatas); | ||
private readComponents(absSourcePath); | ||
constructor(options: AngularCompilerOptions, program: ts.Program, host: ts.CompilerHost, staticReflector: StaticReflector, compiler: compiler.OfflineCompiler, reflectorHost: ReflectorHost); | ||
private readFileMetadata(absSourcePath); | ||
private calculateEmitPath(filePath); | ||
@@ -32,0 +29,0 @@ codegen(): Promise<any>; |
@@ -17,2 +17,3 @@ /** | ||
var compiler_private_1 = require('./compiler_private'); | ||
var core_private_1 = require('./core_private'); | ||
var reflector_host_1 = require('./reflector_host'); | ||
@@ -24,3 +25,3 @@ var static_reflection_capabilities_1 = require('./static_reflection_capabilities'); | ||
var CodeGenerator = (function () { | ||
function CodeGenerator(options, program, host, staticReflector, resolver, compiler, reflectorHost) { | ||
function CodeGenerator(options, program, host, staticReflector, compiler, reflectorHost) { | ||
this.options = options; | ||
@@ -30,26 +31,8 @@ this.program = program; | ||
this.staticReflector = staticReflector; | ||
this.resolver = resolver; | ||
this.compiler = compiler; | ||
this.reflectorHost = reflectorHost; | ||
core_1.lockRunMode(); | ||
} | ||
CodeGenerator.prototype.generateSource = function (metadatas) { | ||
var _this = this; | ||
var normalize = function (metadata) { | ||
var directiveType = metadata.type.runtime; | ||
var directives = _this.resolver.getViewDirectivesMetadata(directiveType); | ||
return Promise.all(directives.map(function (d) { return _this.compiler.normalizeDirectiveMetadata(d); })) | ||
.then(function (normalizedDirectives) { | ||
var pipes = _this.resolver.getViewPipesMetadata(directiveType); | ||
return new compiler.NormalizedComponentWithViewDirectives(metadata, normalizedDirectives, pipes); | ||
}); | ||
}; | ||
return Promise.all(metadatas.map(normalize)) | ||
.then(function (normalizedCompWithDirectives) { | ||
return _this.compiler.compileTemplates(normalizedCompWithDirectives); | ||
}); | ||
}; | ||
CodeGenerator.prototype.readComponents = function (absSourcePath) { | ||
var result = []; | ||
CodeGenerator.prototype.readFileMetadata = function (absSourcePath) { | ||
var moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath); | ||
var result = { components: [], ngModules: [], fileUrl: absSourcePath }; | ||
if (!moduleMetadata) { | ||
@@ -64,15 +47,22 @@ console.log("WARNING: no metadata found for " + absSourcePath); | ||
} | ||
for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) { | ||
var symbol = symbols_1[_i]; | ||
var _loop_1 = function(symbol) { | ||
if (metadata[symbol] && metadata[symbol].__symbolic == 'error') { | ||
// Ignore symbols that are only included to record error information. | ||
continue; | ||
return "continue"; | ||
} | ||
var staticType = this.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath); | ||
var directive = void 0; | ||
directive = this.resolver.maybeGetDirectiveMetadata(staticType); | ||
if (!directive || !directive.isComponent) { | ||
continue; | ||
} | ||
result.push(this.compiler.normalizeDirectiveMetadata(directive)); | ||
var staticType = this_1.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath); | ||
var annotations = this_1.staticReflector.annotations(staticType); | ||
annotations.forEach(function (annotation) { | ||
if (annotation instanceof core_1.NgModuleMetadata) { | ||
result.ngModules.push(staticType); | ||
} | ||
else if (annotation instanceof core_1.ComponentMetadata) { | ||
result.components.push(staticType); | ||
} | ||
}); | ||
}; | ||
var this_1 = this; | ||
for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) { | ||
var symbol = symbols_1[_i]; | ||
_loop_1(symbol); | ||
} | ||
@@ -93,30 +83,31 @@ return result; | ||
} | ||
return path.join(this.options.genDir, path.relative(root, filePath)); | ||
// transplant the codegen path to be inside the `genDir` | ||
var relativePath = path.relative(root, filePath); | ||
while (relativePath.startsWith('..' + path.sep)) { | ||
// Strip out any `..` path such as: `../node_modules/@foo` as we want to put everything | ||
// into `genDir`. | ||
relativePath = relativePath.substr(3); | ||
} | ||
return path.join(this.options.genDir, relativePath); | ||
}; | ||
CodeGenerator.prototype.codegen = function () { | ||
var _this = this; | ||
var generateOneFile = function (absSourcePath) { | ||
return Promise.all(_this.readComponents(absSourcePath)) | ||
.then(function (metadatas) { | ||
if (!metadatas || !metadatas.length) { | ||
return; | ||
} | ||
return _this.generateSource(metadatas); | ||
}) | ||
.then(function (generatedModules) { | ||
if (generatedModules) { | ||
generatedModules.forEach(function (generatedModule) { | ||
var sourceFile = _this.program.getSourceFile(absSourcePath); | ||
var emitPath = _this.calculateEmitPath(generatedModule.moduleUrl); | ||
_this.host.writeFile(emitPath, PREAMBLE + generatedModule.source, false, function () { }, [sourceFile]); | ||
}); | ||
} | ||
}) | ||
.catch(function (e) { console.error(e.stack); }); | ||
}; | ||
var compPromises = this.program.getSourceFiles() | ||
.map(function (sf) { return sf.fileName; }) | ||
.filter(function (f) { return !GENERATED_FILES.test(f); }) | ||
.map(generateOneFile); | ||
return Promise.all(compPromises); | ||
var filePaths = this.program.getSourceFiles().map(function (sf) { return sf.fileName; }).filter(function (f) { return !GENERATED_FILES.test(f); }); | ||
var fileMetas = filePaths.map(function (filePath) { return _this.readFileMetadata(filePath); }); | ||
var ngModules = fileMetas.reduce(function (ngModules, fileMeta) { | ||
ngModules.push.apply(ngModules, fileMeta.ngModules); | ||
return ngModules; | ||
}, []); | ||
var analyzedNgModules = this.compiler.analyzeModules(ngModules); | ||
return Promise | ||
.all(fileMetas.map(function (fileMeta) { return _this.compiler | ||
.compile(fileMeta.fileUrl, analyzedNgModules, fileMeta.components, fileMeta.ngModules) | ||
.then(function (generatedModules) { | ||
generatedModules.forEach(function (generatedModule) { | ||
var sourceFile = _this.program.getSourceFile(fileMeta.fileUrl); | ||
var emitPath = _this.calculateEmitPath(generatedModule.moduleUrl); | ||
_this.host.writeFile(emitPath, PREAMBLE + generatedModule.source, false, function () { }, [sourceFile]); | ||
}); | ||
}); })) | ||
.catch(function (e) { console.error(e.stack); }); | ||
}; | ||
@@ -142,13 +133,12 @@ CodeGenerator.create = function (options, program, compilerHost, reflectorHostContext) { | ||
logBindingUpdate: false, | ||
useJit: false, | ||
platformDirectives: [], | ||
platformPipes: [] | ||
useJit: false | ||
}); | ||
var normalizer = new compiler_private_1.DirectiveNormalizer(xhr, urlResolver, htmlParser, config); | ||
var parser = new compiler_private_1.Parser(new compiler_private_1.Lexer()); | ||
var tmplParser = new compiler_private_1.TemplateParser(parser, new compiler_private_1.DomElementSchemaRegistry(), htmlParser, | ||
/*console*/ null, []); | ||
var offlineCompiler = new compiler.OfflineCompiler(normalizer, tmplParser, new compiler_private_1.StyleCompiler(urlResolver), new compiler_private_1.ViewCompiler(config), new compiler_private_1.TypeScriptEmitter(reflectorHost)); | ||
var resolver = new compiler_private_1.CompileMetadataResolver(new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector), new compiler.ViewResolver(staticReflector), config, staticReflector); | ||
return new CodeGenerator(options, program, compilerHost, staticReflector, resolver, offlineCompiler, reflectorHost); | ||
var expressionParser = new compiler_private_1.Parser(new compiler_private_1.Lexer()); | ||
var elementSchemaRegistry = new compiler_private_1.DomElementSchemaRegistry(); | ||
var console = new core_private_1.Console(); | ||
var tmplParser = new compiler_private_1.TemplateParser(expressionParser, elementSchemaRegistry, htmlParser, console, []); | ||
var resolver = new compiler_private_1.CompileMetadataResolver(new compiler.NgModuleResolver(staticReflector), new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector), config, console, elementSchemaRegistry, staticReflector); | ||
var offlineCompiler = new compiler.OfflineCompiler(resolver, normalizer, tmplParser, new compiler_private_1.StyleCompiler(urlResolver), new compiler_private_1.ViewCompiler(config), new compiler_private_1.NgModuleCompiler(), new compiler_private_1.TypeScriptEmitter(reflectorHost)); | ||
return new CodeGenerator(options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost); | ||
}; | ||
@@ -155,0 +145,0 @@ return CodeGenerator; |
@@ -17,15 +17,6 @@ /** | ||
export declare var HtmlParser: typeof _c.HtmlParser; | ||
export declare type I18nHtmlParser = _c.I18nHtmlParser; | ||
export declare var I18nHtmlParser: typeof _c.I18nHtmlParser; | ||
export declare type MessageExtractor = _c.MessageExtractor; | ||
export declare var MessageExtractor: typeof _c.MessageExtractor; | ||
export declare type ExtractionResult = _c.ExtractionResult; | ||
export declare var ExtractionResult: typeof _c.ExtractionResult; | ||
export declare type Message = _c.Message; | ||
export declare var Message: typeof _c.Message; | ||
export declare var removeDuplicates: typeof _c.removeDuplicates; | ||
export declare var serializeXmb: typeof _c.serializeXmb; | ||
export declare var deserializeXmb: typeof _c.deserializeXmb; | ||
export declare type ParseError = _c.ParseError; | ||
export declare var ParseError: typeof _c.ParseError; | ||
export declare type InterpolationConfig = _c.InterpolationConfig; | ||
export declare var InterpolationConfig: typeof _c.InterpolationConfig; | ||
export declare type DirectiveNormalizer = _c.DirectiveNormalizer; | ||
@@ -45,3 +36,5 @@ export declare var DirectiveNormalizer: typeof _c.DirectiveNormalizer; | ||
export declare var ViewCompiler: typeof _c.ViewCompiler; | ||
export declare type NgModuleCompiler = _c.NgModuleCompiler; | ||
export declare var NgModuleCompiler: typeof _c.NgModuleCompiler; | ||
export declare type TypeScriptEmitter = _c.TypeScriptEmitter; | ||
export declare var TypeScriptEmitter: typeof _c.TypeScriptEmitter; |
@@ -14,10 +14,4 @@ /** | ||
exports.HtmlParser = compiler_1.__compiler_private__.HtmlParser; | ||
exports.I18nHtmlParser = compiler_1.__compiler_private__.I18nHtmlParser; | ||
exports.MessageExtractor = compiler_1.__compiler_private__.MessageExtractor; | ||
exports.ExtractionResult = compiler_1.__compiler_private__.ExtractionResult; | ||
exports.Message = compiler_1.__compiler_private__.Message; | ||
exports.removeDuplicates = compiler_1.__compiler_private__.removeDuplicates; | ||
exports.serializeXmb = compiler_1.__compiler_private__.serializeXmb; | ||
exports.deserializeXmb = compiler_1.__compiler_private__.deserializeXmb; | ||
exports.ParseError = compiler_1.__compiler_private__.ParseError; | ||
exports.InterpolationConfig = compiler_1.__compiler_private__.InterpolationConfig; | ||
exports.DirectiveNormalizer = compiler_1.__compiler_private__.DirectiveNormalizer; | ||
@@ -30,3 +24,4 @@ exports.Lexer = compiler_1.__compiler_private__.Lexer; | ||
exports.ViewCompiler = compiler_1.__compiler_private__.ViewCompiler; | ||
exports.NgModuleCompiler = compiler_1.__compiler_private__.NgModuleCompiler; | ||
exports.TypeScriptEmitter = compiler_1.__compiler_private__.TypeScriptEmitter; | ||
//# sourceMappingURL=compiler_private.js.map |
@@ -1,1 +0,1 @@ | ||
{"__symbolic":"module","version":1,"metadata":{"AssetUrl":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"AssetUrl"},"ImportGenerator":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ImportGenerator"},"CompileMetadataResolver":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"CompileMetadataResolver"},"HtmlParser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"HtmlParser"},"I18nHtmlParser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"I18nHtmlParser"},"MessageExtractor":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"MessageExtractor"},"ExtractionResult":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ExtractionResult"},"Message":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"Message"},"removeDuplicates":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"removeDuplicates"},"serializeXmb":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"serializeXmb"},"deserializeXmb":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"deserializeXmb"},"ParseError":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ParseError"},"DirectiveNormalizer":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"DirectiveNormalizer"},"Lexer":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"Lexer"},"Parser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"Parser"},"TemplateParser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"TemplateParser"},"DomElementSchemaRegistry":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"DomElementSchemaRegistry"},"StyleCompiler":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"StyleCompiler"},"ViewCompiler":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ViewCompiler"},"TypeScriptEmitter":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"TypeScriptEmitter"}}} | ||
{"__symbolic":"module","version":1,"metadata":{"AssetUrl":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"AssetUrl"},"ImportGenerator":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ImportGenerator"},"CompileMetadataResolver":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"CompileMetadataResolver"},"HtmlParser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"HtmlParser"},"ParseError":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ParseError"},"InterpolationConfig":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"InterpolationConfig"},"DirectiveNormalizer":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"DirectiveNormalizer"},"Lexer":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"Lexer"},"Parser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"Parser"},"TemplateParser":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"TemplateParser"},"DomElementSchemaRegistry":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"DomElementSchemaRegistry"},"StyleCompiler":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"StyleCompiler"},"ViewCompiler":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"ViewCompiler"},"NgModuleCompiler":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"NgModuleCompiler"},"TypeScriptEmitter":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/compiler","name":"___compiler_private__"},"member":"TypeScriptEmitter"}}} |
@@ -13,2 +13,4 @@ /** | ||
export declare var ReflectionCapabilities: typeof t.ReflectionCapabilities; | ||
export declare type Console = t.Console; | ||
export declare var Console: typeof t.Console; | ||
export declare var reflector: typeof t.reflector; |
@@ -12,3 +12,4 @@ /** | ||
exports.ReflectionCapabilities = core_1.__core_private__.ReflectionCapabilities; | ||
exports.Console = core_1.__core_private__.Console; | ||
exports.reflector = core_1.__core_private__.reflector; | ||
//# sourceMappingURL=core_private.js.map |
@@ -1,1 +0,1 @@ | ||
{"__symbolic":"module","version":1,"metadata":{"ReflectorReader":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"ReflectorReader"},"ReflectionCapabilities":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"ReflectionCapabilities"},"reflector":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"reflector"}}} | ||
{"__symbolic":"module","version":1,"metadata":{"ReflectorReader":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"ReflectorReader"},"ReflectionCapabilities":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"ReflectionCapabilities"},"Console":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"Console"},"reflector":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"___core_private__"},"member":"reflector"}}} |
import 'reflect-metadata'; | ||
import * as compiler from '@angular/compiler'; | ||
import * as ts from 'typescript'; | ||
import * as tsc from '@angular/tsc-wrapped'; | ||
import { CompileMetadataResolver, DirectiveNormalizer } from './compiler_private'; | ||
import { ReflectorHost, ReflectorHostContext } from './reflector_host'; | ||
import { StaticReflector } from './static_reflector'; | ||
export declare class Extractor { | ||
private program; | ||
host: ts.CompilerHost; | ||
private staticReflector; | ||
private messageBundle; | ||
private reflectorHost; | ||
private metadataResolver; | ||
private directiveNormalizer; | ||
private compiler; | ||
constructor(program: ts.Program, host: ts.CompilerHost, staticReflector: StaticReflector, messageBundle: compiler.i18n.MessageBundle, reflectorHost: ReflectorHost, metadataResolver: CompileMetadataResolver, directiveNormalizer: DirectiveNormalizer, compiler: compiler.OfflineCompiler); | ||
private readFileMetadata(absSourcePath); | ||
extract(): Promise<compiler.i18n.MessageBundle>; | ||
static create(options: tsc.AngularCompilerOptions, program: ts.Program, compilerHost: ts.CompilerHost, reflectorHostContext?: ReflectorHostContext): Extractor; | ||
} |
#!/usr/bin/env node | ||
"use strict"; | ||
require('reflect-metadata'); | ||
var tsc = require('@angular/tsc-wrapped'); | ||
var path = require('path'); | ||
var compiler = require('@angular/compiler'); | ||
var core_1 = require('@angular/core'); | ||
var static_reflector_1 = require('./static_reflector'); | ||
var path = require('path'); | ||
var tsc = require('@angular/tsc-wrapped'); | ||
var compiler_private_1 = require('./compiler_private'); | ||
var core_private_1 = require('./core_private'); | ||
var reflector_host_1 = require('./reflector_host'); | ||
var static_reflection_capabilities_1 = require('./static_reflection_capabilities'); | ||
var static_reflector_1 = require('./static_reflector'); | ||
function extract(ngOptions, program, host) { | ||
return Extractor.create(ngOptions, program, host).extract(); | ||
var extractor = Extractor.create(ngOptions, program, host); | ||
var bundlePromise = extractor.extract(); | ||
return (bundlePromise).then(function (messageBundle) { | ||
var serializer = new compiler.i18n.Xmb(); | ||
var dstPath = path.join(ngOptions.genDir, 'messages.xmb'); | ||
host.writeFile(dstPath, messageBundle.write(serializer), false); | ||
}); | ||
} | ||
var _dirPaths = new Map(); | ||
var _GENERATED_FILES = /\.ngfactory\.ts$|\.css\.ts$|\.css\.shim\.ts$/; | ||
var GENERATED_FILES = /\.ngfactory\.ts$|\.css\.ts$|\.css\.shim\.ts$/; | ||
var Extractor = (function () { | ||
function Extractor(_options, _program, host, staticReflector, _resolver, _compiler, _reflectorHost, _extractor) { | ||
this._options = _options; | ||
this._program = _program; | ||
function Extractor(program, host, staticReflector, messageBundle, reflectorHost, metadataResolver, directiveNormalizer, compiler) { | ||
this.program = program; | ||
this.host = host; | ||
this.staticReflector = staticReflector; | ||
this._resolver = _resolver; | ||
this._compiler = _compiler; | ||
this._reflectorHost = _reflectorHost; | ||
this._extractor = _extractor; | ||
core_1.lockRunMode(); | ||
this.messageBundle = messageBundle; | ||
this.reflectorHost = reflectorHost; | ||
this.metadataResolver = metadataResolver; | ||
this.directiveNormalizer = directiveNormalizer; | ||
this.compiler = compiler; | ||
} | ||
Extractor.prototype._extractCmpMessages = function (metadatas) { | ||
var _this = this; | ||
if (!metadatas || !metadatas.length) { | ||
return null; | ||
} | ||
var normalize = function (metadata) { | ||
var directiveType = metadata.type.runtime; | ||
var directives = _this._resolver.getViewDirectivesMetadata(directiveType); | ||
return Promise.all(directives.map(function (d) { return _this._compiler.normalizeDirectiveMetadata(d); })) | ||
.then(function (normalizedDirectives) { | ||
var pipes = _this._resolver.getViewPipesMetadata(directiveType); | ||
return new compiler.NormalizedComponentWithViewDirectives(metadata, normalizedDirectives, pipes); | ||
}); | ||
}; | ||
return Promise.all(metadatas.map(normalize)) | ||
.then(function (cmps) { | ||
var messages = []; | ||
var errors = []; | ||
cmps.forEach(function (cmp) { | ||
var url = _dirPaths.get(cmp.component); | ||
var result = _this._extractor.extract(cmp.component.template.template, url); | ||
errors = errors.concat(result.errors); | ||
messages = messages.concat(result.messages); | ||
}); | ||
// Extraction Result might contain duplicate messages at this point | ||
return new compiler_private_1.ExtractionResult(messages, errors); | ||
}); | ||
}; | ||
Extractor.prototype._readComponents = function (absSourcePath) { | ||
var result = []; | ||
var metadata = this.staticReflector.getModuleMetadata(absSourcePath); | ||
if (!metadata) { | ||
Extractor.prototype.readFileMetadata = function (absSourcePath) { | ||
var moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath); | ||
var result = { components: [], ngModules: [], fileUrl: absSourcePath }; | ||
if (!moduleMetadata) { | ||
console.log("WARNING: no metadata found for " + absSourcePath); | ||
return result; | ||
} | ||
var symbols = Object.keys(metadata['metadata']); | ||
var metadata = moduleMetadata['metadata']; | ||
var symbols = metadata && Object.keys(metadata); | ||
if (!symbols || !symbols.length) { | ||
return result; | ||
} | ||
var _loop_1 = function(symbol) { | ||
if (metadata[symbol] && metadata[symbol].__symbolic == 'error') { | ||
// Ignore symbols that are only included to record error information. | ||
return "continue"; | ||
} | ||
var staticType = this_1.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath); | ||
var annotations = this_1.staticReflector.annotations(staticType); | ||
annotations.forEach(function (annotation) { | ||
if (annotation instanceof core_1.NgModuleMetadata) { | ||
result.ngModules.push(staticType); | ||
} | ||
else if (annotation instanceof core_1.ComponentMetadata) { | ||
result.components.push(staticType); | ||
} | ||
}); | ||
}; | ||
var this_1 = this; | ||
for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) { | ||
var symbol = symbols_1[_i]; | ||
var staticType = this._reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath); | ||
var directive = void 0; | ||
directive = this._resolver.maybeGetDirectiveMetadata(staticType); | ||
if (directive && directive.isComponent) { | ||
var promise = this._compiler.normalizeDirectiveMetadata(directive); | ||
promise.then(function (md) { return _dirPaths.set(md, absSourcePath); }); | ||
result.push(promise); | ||
} | ||
_loop_1(symbol); | ||
} | ||
@@ -83,28 +71,39 @@ return result; | ||
var _this = this; | ||
_dirPaths.clear(); | ||
var promises = this._program.getSourceFiles() | ||
.map(function (sf) { return sf.fileName; }) | ||
.filter(function (f) { return !_GENERATED_FILES.test(f); }) | ||
.map(function (absSourcePath) { | ||
return Promise.all(_this._readComponents(absSourcePath)) | ||
.then(function (metadatas) { return _this._extractCmpMessages(metadatas); }) | ||
.catch(function (e) { return console.error(e.stack); }); | ||
}); | ||
var messages = []; | ||
var filePaths = this.program.getSourceFiles().map(function (sf) { return sf.fileName; }).filter(function (f) { return !GENERATED_FILES.test(f); }); | ||
var fileMetas = filePaths.map(function (filePath) { return _this.readFileMetadata(filePath); }); | ||
var ngModules = fileMetas.reduce(function (ngModules, fileMeta) { | ||
ngModules.push.apply(ngModules, fileMeta.ngModules); | ||
return ngModules; | ||
}, []); | ||
var analyzedNgModules = this.compiler.analyzeModules(ngModules); | ||
var errors = []; | ||
return Promise.all(promises).then(function (extractionResults) { | ||
extractionResults.filter(function (result) { return !!result; }).forEach(function (result) { | ||
messages = messages.concat(result.messages); | ||
errors = errors.concat(result.errors); | ||
}); | ||
if (errors.length) { | ||
throw new Error(errors.map(function (e) { return e.toString(); }).join('\n')); | ||
} | ||
messages = compiler_private_1.removeDuplicates(messages); | ||
var genPath = path.join(_this._options.genDir, 'messages.xmb'); | ||
var msgBundle = compiler_private_1.serializeXmb(messages); | ||
_this.host.writeFile(genPath, msgBundle, false); | ||
}); | ||
var bundlePromise = Promise | ||
.all(fileMetas.map(function (fileMeta) { | ||
var url = fileMeta.fileUrl; | ||
return Promise.all(fileMeta.components.map(function (compType) { | ||
var compMeta = _this.metadataResolver.getDirectiveMetadata(compType); | ||
var ngModule = analyzedNgModules.ngModuleByComponent.get(compType); | ||
if (!ngModule) { | ||
throw new Error("Cannot determine the module for component " + compMeta.type.name + "!"); | ||
} | ||
return Promise | ||
.all([compMeta].concat(ngModule.transitiveModule.directives).map(function (dirMeta) { | ||
return _this.directiveNormalizer.normalizeDirective(dirMeta).asyncResult; | ||
})) | ||
.then(function (normalizedCompWithDirectives) { | ||
var compMeta = normalizedCompWithDirectives[0]; | ||
var html = compMeta.template.template; | ||
var interpolationConfig = compiler.InterpolationConfig.fromArray(compMeta.template.interpolation); | ||
errors.push.apply(errors, _this.messageBundle.updateFromTemplate(html, url, interpolationConfig)); | ||
}); | ||
})); | ||
})) | ||
.then(function (_) { return _this.messageBundle; }) | ||
.catch(function (e) { console.error(e.stack); }); | ||
if (errors.length) { | ||
throw new Error(errors.map(function (e) { return e.toString(); }).join('\n')); | ||
} | ||
return bundlePromise; | ||
}; | ||
Extractor.create = function (options, program, compilerHost) { | ||
Extractor.create = function (options, program, compilerHost, reflectorHostContext) { | ||
var xhr = { | ||
@@ -120,3 +119,3 @@ get: function (s) { | ||
var urlResolver = compiler.createOfflineCompileUrlResolver(); | ||
var reflectorHost = new reflector_host_1.ReflectorHost(program, compilerHost, options); | ||
var reflectorHost = new reflector_host_1.ReflectorHost(program, compilerHost, options, reflectorHostContext); | ||
var staticReflector = new static_reflector_1.StaticReflector(reflectorHost); | ||
@@ -126,21 +125,21 @@ static_reflection_capabilities_1.StaticAndDynamicReflectionCapabilities.install(staticReflector); | ||
var config = new compiler.CompilerConfig({ | ||
genDebugInfo: true, | ||
genDebugInfo: options.debug === true, | ||
defaultEncapsulation: core_1.ViewEncapsulation.Emulated, | ||
logBindingUpdate: false, | ||
useJit: false, | ||
platformDirectives: [], | ||
platformPipes: [] | ||
useJit: false | ||
}); | ||
var normalizer = new compiler_private_1.DirectiveNormalizer(xhr, urlResolver, htmlParser, config); | ||
var parser = new compiler_private_1.Parser(new compiler_private_1.Lexer()); | ||
var tmplParser = new compiler_private_1.TemplateParser(parser, new compiler_private_1.DomElementSchemaRegistry(), htmlParser, | ||
/*console*/ null, []); | ||
var offlineCompiler = new compiler.OfflineCompiler(normalizer, tmplParser, new compiler_private_1.StyleCompiler(urlResolver), new compiler_private_1.ViewCompiler(config), new compiler_private_1.TypeScriptEmitter(reflectorHost)); | ||
var resolver = new compiler_private_1.CompileMetadataResolver(new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector), new compiler.ViewResolver(staticReflector), config, staticReflector); | ||
// TODO(vicb): handle implicit | ||
var extractor = new compiler_private_1.MessageExtractor(htmlParser, parser, [], {}); | ||
return new Extractor(options, program, compilerHost, staticReflector, resolver, offlineCompiler, reflectorHost, extractor); | ||
var expressionParser = new compiler_private_1.Parser(new compiler_private_1.Lexer()); | ||
var elementSchemaRegistry = new compiler_private_1.DomElementSchemaRegistry(); | ||
var console = new core_private_1.Console(); | ||
var tmplParser = new compiler_private_1.TemplateParser(expressionParser, elementSchemaRegistry, htmlParser, console, []); | ||
var resolver = new compiler_private_1.CompileMetadataResolver(new compiler.NgModuleResolver(staticReflector), new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector), config, console, elementSchemaRegistry, staticReflector); | ||
var offlineCompiler = new compiler.OfflineCompiler(resolver, normalizer, tmplParser, new compiler_private_1.StyleCompiler(urlResolver), new compiler_private_1.ViewCompiler(config), new compiler_private_1.NgModuleCompiler(), new compiler_private_1.TypeScriptEmitter(reflectorHost)); | ||
// TODO(vicb): implicit tags & attributes | ||
var messageBundle = new compiler.i18n.MessageBundle(htmlParser, [], {}); | ||
return new Extractor(program, compilerHost, staticReflector, messageBundle, reflectorHost, resolver, normalizer, offlineCompiler); | ||
}; | ||
return Extractor; | ||
}()); | ||
exports.Extractor = Extractor; | ||
// Entry point | ||
@@ -153,3 +152,3 @@ if (require.main === module) { | ||
console.error(e.stack); | ||
console.error('Compilation failed'); | ||
console.error('Extraction failed'); | ||
process.exit(1); | ||
@@ -156,0 +155,0 @@ }); |
@@ -13,5 +13,6 @@ /** | ||
export interface ReflectorHostContext { | ||
exists(fileName: string): boolean; | ||
read(fileName: string): string; | ||
write(fileName: string, data: string): void; | ||
fileExists(fileName: string): boolean; | ||
directoryExists(directoryName: string): boolean; | ||
readFile(fileName: string): string; | ||
assumeFileExists(fileName: string): void; | ||
} | ||
@@ -24,2 +25,5 @@ export declare class ReflectorHost implements StaticReflectorHost, ImportGenerator { | ||
private context; | ||
private isGenDirChildOfRootDir; | ||
private basePath; | ||
private genDir; | ||
constructor(program: ts.Program, compilerHost: ts.CompilerHost, options: AngularCompilerOptions, context?: ReflectorHostContext); | ||
@@ -40,8 +44,23 @@ angularImportLocations(): { | ||
* These need to be in a form that system.js can load, so absolute file paths don't work. | ||
* Relativize the paths by checking candidate prefixes of the absolute path, to see if | ||
* they are resolvable by the moduleResolution strategy from the CompilerHost. | ||
* | ||
* The `containingFile` is always in the `genDir`, where as the `importedFile` can be in | ||
* `genDir`, `node_module` or `basePath`. The `importedFile` is either a generated file or | ||
* existing file. | ||
* | ||
* | genDir | node_module | rootDir | ||
* --------------+----------+-------------+---------- | ||
* generated | relative | relative | n/a | ||
* existing file | n/a | absolute | relative(*) | ||
* | ||
* NOTE: (*) the relative path is computed depending on `isGenDirChildOfRootDir`. | ||
*/ | ||
getImportPath(containingFile: string, importedFile: string): string; | ||
private dotRelative(from, to); | ||
/** | ||
* Moves the path into `genDir` folder while preserving the `node_modules` directory. | ||
*/ | ||
private rewriteGenDirPath(filepath); | ||
findDeclaration(module: string, symbolName: string, containingFile: string, containingModule?: string): StaticSymbol; | ||
private typeCache; | ||
private resolverCache; | ||
/** | ||
@@ -57,7 +76,11 @@ * getStaticSymbol produces a Type whose metadata is known but whose implementation is not loaded. | ||
readMetadata(filePath: string): any; | ||
private getResolverMetadata(filePath); | ||
private resolveExportedSymbol(filePath, symbolName); | ||
} | ||
export declare class NodeReflectorHostContext implements ReflectorHostContext { | ||
exists(fileName: string): boolean; | ||
read(fileName: string): string; | ||
write(fileName: string, data: string): void; | ||
private assumedExists; | ||
fileExists(fileName: string): boolean; | ||
directoryExists(directoryName: string): boolean; | ||
readFile(fileName: string): string; | ||
assumeFileExists(fileName: string): void; | ||
} |
@@ -17,2 +17,4 @@ /** | ||
var DTS = /\.d\.ts$/; | ||
var NODE_MODULES = path.sep + 'node_modules' + path.sep; | ||
var IS_GENERATED = /\.(ngfactory|css(\.shim)?)$/; | ||
var ReflectorHost = (function () { | ||
@@ -25,3 +27,9 @@ function ReflectorHost(program, compilerHost, options, context) { | ||
this.typeCache = new Map(); | ||
this.resolverCache = new Map(); | ||
// normalize the path so that it never ends with '/'. | ||
this.basePath = path.normalize(path.join(this.options.basePath, '.')); | ||
this.genDir = path.normalize(path.join(this.options.genDir, '.')); | ||
this.context = context || new NodeReflectorHostContext(); | ||
var genPath = path.relative(this.basePath, this.genDir); | ||
this.isGenDirChildOfRootDir = genPath === '' || !genPath.startsWith('..'); | ||
} | ||
@@ -39,3 +47,3 @@ ReflectorHost.prototype.angularImportLocations = function () { | ||
ReflectorHost.prototype.resolve = function (m, containingFile) { | ||
var resolved = ts.resolveModuleName(m, containingFile, this.options, this.compilerHost).resolvedModule; | ||
var resolved = ts.resolveModuleName(m, containingFile, this.options, this.context).resolvedModule; | ||
return resolved ? resolved.resolvedFileName : null; | ||
@@ -58,4 +66,13 @@ }; | ||
* These need to be in a form that system.js can load, so absolute file paths don't work. | ||
* Relativize the paths by checking candidate prefixes of the absolute path, to see if | ||
* they are resolvable by the moduleResolution strategy from the CompilerHost. | ||
* | ||
* The `containingFile` is always in the `genDir`, where as the `importedFile` can be in | ||
* `genDir`, `node_module` or `basePath`. The `importedFile` is either a generated file or | ||
* existing file. | ||
* | ||
* | genDir | node_module | rootDir | ||
* --------------+----------+-------------+---------- | ||
* generated | relative | relative | n/a | ||
* existing file | n/a | absolute | relative(*) | ||
* | ||
* NOTE: (*) the relative path is computed depending on `isGenDirChildOfRootDir`. | ||
*/ | ||
@@ -65,28 +82,60 @@ ReflectorHost.prototype.getImportPath = function (containingFile, importedFile) { | ||
containingFile = this.resolveAssetUrl(containingFile, ''); | ||
// TODO(tbosch): if a file does not yet exist (because we compile it later), | ||
// we still need to create it so that the `resolve` method works! | ||
// If a file does not yet exist (because we compile it later), we still need to | ||
// assume it exists it so that the `resolve` method works! | ||
if (!this.compilerHost.fileExists(importedFile)) { | ||
if (this.options.trace) { | ||
console.log("Generating empty file " + importedFile + " to allow resolution of import"); | ||
this.context.assumeFileExists(importedFile); | ||
} | ||
containingFile = this.rewriteGenDirPath(containingFile); | ||
var containingDir = path.dirname(containingFile); | ||
// drop extension | ||
importedFile = importedFile.replace(EXT, ''); | ||
var nodeModulesIndex = importedFile.indexOf(NODE_MODULES); | ||
var importModule = nodeModulesIndex === -1 ? | ||
null : | ||
importedFile.substring(nodeModulesIndex + NODE_MODULES.length); | ||
var isGeneratedFile = IS_GENERATED.test(importedFile); | ||
if (isGeneratedFile) { | ||
// rewrite to genDir path | ||
if (importModule) { | ||
// it is generated, therefore we do a relative path to the factory | ||
return this.dotRelative(containingDir, this.genDir + NODE_MODULES + importModule); | ||
} | ||
this.compilerHost.writeFile(importedFile, '', false); | ||
this.context.write(importedFile, ''); | ||
else { | ||
// assume that import is also in `genDir` | ||
importedFile = this.rewriteGenDirPath(importedFile); | ||
return this.dotRelative(containingDir, importedFile); | ||
} | ||
} | ||
var importModuleName = importedFile.replace(EXT, ''); | ||
var parts = importModuleName.split(path.sep).filter(function (p) { return !!p; }); | ||
for (var index = parts.length - 1; index >= 0; index--) { | ||
var candidate_1 = parts.slice(index, parts.length).join(path.sep); | ||
if (this.resolve('.' + path.sep + candidate_1, containingFile) === importedFile) { | ||
return "./" + candidate_1; | ||
else { | ||
// user code import | ||
if (importModule) { | ||
return importModule; | ||
} | ||
if (this.resolve(candidate_1, containingFile) === importedFile) { | ||
return candidate_1; | ||
else { | ||
if (!this.isGenDirChildOfRootDir) { | ||
// assume that they are on top of each other. | ||
importedFile = importedFile.replace(this.basePath, this.genDir); | ||
} | ||
return this.dotRelative(containingDir, importedFile); | ||
} | ||
} | ||
// Try a relative import | ||
var candidate = path.relative(path.dirname(containingFile), importModuleName); | ||
if (this.resolve(candidate, containingFile) === importedFile) { | ||
return candidate; | ||
}; | ||
ReflectorHost.prototype.dotRelative = function (from, to) { | ||
var rPath = path.relative(from, to); | ||
return rPath.startsWith('.') ? rPath : './' + rPath; | ||
}; | ||
/** | ||
* Moves the path into `genDir` folder while preserving the `node_modules` directory. | ||
*/ | ||
ReflectorHost.prototype.rewriteGenDirPath = function (filepath) { | ||
var nodeModulesIndex = filepath.indexOf(NODE_MODULES); | ||
if (nodeModulesIndex !== -1) { | ||
// If we are in node_modulse, transplant them into `genDir`. | ||
return path.join(this.genDir, filepath.substring(nodeModulesIndex)); | ||
} | ||
throw new Error("Unable to find any resolvable import for " + importedFile + " relative to " + containingFile); | ||
else { | ||
// pretend that containing file is on top of the `genDir` to normalize the paths. | ||
// we apply the `genDir` => `rootDir` delta through `rootDirPrefix` later. | ||
return filepath.replace(this.basePath, this.genDir); | ||
} | ||
}; | ||
@@ -99,3 +148,3 @@ ReflectorHost.prototype.findDeclaration = function (module, symbolName, containingFile, containingModule) { | ||
// Any containing file gives the same result for absolute imports | ||
containingFile = path.join(this.options.basePath, 'index.ts'); | ||
containingFile = path.join(this.basePath, 'index.ts'); | ||
} | ||
@@ -109,3 +158,6 @@ try { | ||
if (!filePath) { | ||
throw new Error("Could not resolve module " + module + " relative to " + containingFile); | ||
// If the file cannot be found the module is probably referencing a declared module | ||
// for which there is no disambiguating file and we also don't need to track | ||
// re-exports. Just use the module name. | ||
return this.getStaticSymbol(module, symbolName); | ||
} | ||
@@ -116,7 +168,6 @@ var tc = this.program.getTypeChecker(); | ||
// The source file was not needed in the compile but we do need the values from | ||
// the corresponding .ts files stored in the .metadata.json file. Just assume the | ||
// symbol and file we resolved to be correct as we don't need this to be the | ||
// cannonical reference as this reference could have only been generated by a | ||
// .metadata.json file resolving values. | ||
return this.getStaticSymbol(filePath, symbolName); | ||
// the corresponding .ts files stored in the .metadata.json file. Check the file | ||
// for exports to see if the file is exported. | ||
return this.resolveExportedSymbol(filePath, symbolName) || | ||
this.getStaticSymbol(filePath, symbolName); | ||
} | ||
@@ -156,24 +207,26 @@ var symbol = tc.getExportsOfModule(sf.symbol).find(function (m) { return m.name === symbolName; }); | ||
}; | ||
// TODO(alexeagle): take a statictype | ||
ReflectorHost.prototype.getMetadataFor = function (filePath) { | ||
if (!this.context.exists(filePath)) { | ||
throw new Error("No such file '" + filePath + "'"); | ||
if (!this.context.fileExists(filePath)) { | ||
// If the file doesn't exists then we cannot return metadata for the file. | ||
// This will occur if the user refernced a declared module for which no file | ||
// exists for the module (i.e. jQuery or angularjs). | ||
return; | ||
} | ||
if (DTS.test(filePath)) { | ||
var metadataPath = filePath.replace(DTS, '.metadata.json'); | ||
if (this.context.exists(metadataPath)) { | ||
if (this.context.fileExists(metadataPath)) { | ||
return this.readMetadata(metadataPath); | ||
} | ||
} | ||
var sf = this.program.getSourceFile(filePath); | ||
if (!sf) { | ||
throw new Error("Source file " + filePath + " not present in program."); | ||
else { | ||
var sf = this.program.getSourceFile(filePath); | ||
if (!sf) { | ||
throw new Error("Source file " + filePath + " not present in program."); | ||
} | ||
return this.metadataCollector.getMetadata(sf); | ||
} | ||
var metadata = this.metadataCollector.getMetadata(sf); | ||
return metadata; | ||
}; | ||
ReflectorHost.prototype.readMetadata = function (filePath) { | ||
try { | ||
var result = JSON.parse(this.context.read(filePath)); | ||
return result; | ||
return this.resolverCache.get(filePath) || JSON.parse(this.context.readFile(filePath)); | ||
} | ||
@@ -185,2 +238,62 @@ catch (e) { | ||
}; | ||
ReflectorHost.prototype.getResolverMetadata = function (filePath) { | ||
var metadata = this.resolverCache.get(filePath); | ||
if (!metadata) { | ||
metadata = this.getMetadataFor(filePath); | ||
this.resolverCache.set(filePath, metadata); | ||
} | ||
return metadata; | ||
}; | ||
ReflectorHost.prototype.resolveExportedSymbol = function (filePath, symbolName) { | ||
var _this = this; | ||
var resolveModule = function (moduleName) { | ||
var resolvedModulePath = _this.resolve(moduleName, filePath); | ||
if (!resolvedModulePath) { | ||
throw new Error("Could not resolve module '" + moduleName + "' relative to file " + filePath); | ||
} | ||
return resolvedModulePath; | ||
}; | ||
var metadata = this.getResolverMetadata(filePath); | ||
if (metadata) { | ||
// If we have metadata for the symbol, this is the original exporting location. | ||
if (metadata.metadata[symbolName]) { | ||
return this.getStaticSymbol(filePath, symbolName); | ||
} | ||
// If no, try to find the symbol in one of the re-export location | ||
if (metadata.exports) { | ||
// Try and find the symbol in the list of explicitly re-exported symbols. | ||
for (var _i = 0, _a = metadata.exports; _i < _a.length; _i++) { | ||
var moduleExport = _a[_i]; | ||
if (moduleExport.export) { | ||
var exportSymbol = moduleExport.export.find(function (symbol) { | ||
if (typeof symbol === 'string') { | ||
return symbol == symbolName; | ||
} | ||
else { | ||
return symbol.as == symbolName; | ||
} | ||
}); | ||
if (exportSymbol) { | ||
var symName = symbolName; | ||
if (typeof exportSymbol !== 'string') { | ||
symName = exportSymbol.name; | ||
} | ||
return this.resolveExportedSymbol(resolveModule(moduleExport.from), symName); | ||
} | ||
} | ||
} | ||
// Try to find the symbol via export * directives. | ||
for (var _b = 0, _c = metadata.exports; _b < _c.length; _b++) { | ||
var moduleExport = _c[_b]; | ||
if (!moduleExport.export) { | ||
var resolvedModule = resolveModule(moduleExport.from); | ||
var candidateSymbol = this.resolveExportedSymbol(resolvedModule, symbolName); | ||
if (candidateSymbol) | ||
return candidateSymbol; | ||
} | ||
} | ||
} | ||
} | ||
return null; | ||
}; | ||
return ReflectorHost; | ||
@@ -191,6 +304,17 @@ }()); | ||
function NodeReflectorHostContext() { | ||
this.assumedExists = {}; | ||
} | ||
NodeReflectorHostContext.prototype.exists = function (fileName) { return fs.existsSync(fileName); }; | ||
NodeReflectorHostContext.prototype.read = function (fileName) { return fs.readFileSync(fileName, 'utf8'); }; | ||
NodeReflectorHostContext.prototype.write = function (fileName, data) { fs.writeFileSync(fileName, data, 'utf8'); }; | ||
NodeReflectorHostContext.prototype.fileExists = function (fileName) { | ||
return this.assumedExists[fileName] || fs.existsSync(fileName); | ||
}; | ||
NodeReflectorHostContext.prototype.directoryExists = function (directoryName) { | ||
try { | ||
return fs.statSync(directoryName).isDirectory(); | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
}; | ||
NodeReflectorHostContext.prototype.readFile = function (fileName) { return fs.readFileSync(fileName, 'utf8'); }; | ||
NodeReflectorHostContext.prototype.assumeFileExists = function (fileName) { this.assumedExists[fileName] = true; }; | ||
return NodeReflectorHostContext; | ||
@@ -197,0 +321,0 @@ }()); |
@@ -68,3 +68,4 @@ /** | ||
propMetadata = mapStringMap(members, function (propData, propName) { | ||
var prop = propData.find(function (a) { return a['__symbolic'] == 'property'; }); | ||
var prop = propData | ||
.find(function (a) { return a['__symbolic'] == 'property' || a['__symbolic'] == 'method'; }); | ||
if (prop && prop['decorators']) { | ||
@@ -163,2 +164,3 @@ return _this.simplify(type, prop['decorators']); | ||
this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Component'), core_1.ComponentMetadata); | ||
this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'NgModule'), core_1.NgModuleMetadata); | ||
// Note: Some metadata classes can be used directly with Provider.deps. | ||
@@ -184,3 +186,3 @@ this.registerDecoratorOrConstructor(this.host.findDeclaration(diMetadata, 'HostMetadata'), core_1.HostMetadata); | ||
function simplifyInContext(context, value, depth) { | ||
function resolveReference(expression) { | ||
function resolveReference(context, expression) { | ||
var staticSymbol; | ||
@@ -195,7 +197,13 @@ if (expression['module']) { | ||
} | ||
function isOpaqueToken(value) { | ||
function resolveReferenceValue(staticSymbol) { | ||
var result = staticSymbol; | ||
var moduleMetadata = _this.getModuleMetadata(staticSymbol.filePath); | ||
var declarationValue = moduleMetadata ? moduleMetadata['metadata'][staticSymbol.name] : null; | ||
return declarationValue; | ||
} | ||
function isOpaqueToken(context, value) { | ||
if (value && value.__symbolic === 'new' && value.expression) { | ||
var target = value.expression; | ||
if (target.__symbolic == 'reference') { | ||
return sameSymbol(resolveReference(target), _this.opaqueToken); | ||
return sameSymbol(resolveReference(context, target), _this.opaqueToken); | ||
} | ||
@@ -206,35 +214,61 @@ } | ||
function simplifyCall(expression) { | ||
var context = undefined; | ||
var callContext = undefined; | ||
if (expression['__symbolic'] == 'call') { | ||
var target = expression['expression']; | ||
if (target && target.__symbolic === 'reference') { | ||
context = { name: target.name }; | ||
var functionSymbol = void 0; | ||
var targetFunction = void 0; | ||
if (target) { | ||
switch (target.__symbolic) { | ||
case 'reference': | ||
// Find the function to call. | ||
callContext = { name: target.name }; | ||
functionSymbol = resolveReference(context, target); | ||
targetFunction = resolveReferenceValue(functionSymbol); | ||
break; | ||
case 'select': | ||
// Find the static method to call | ||
if (target.expression.__symbolic == 'reference') { | ||
functionSymbol = resolveReference(context, target.expression); | ||
var classData = resolveReferenceValue(functionSymbol); | ||
if (classData && classData.statics) { | ||
targetFunction = classData.statics[target.member]; | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
var targetFunction = simplify(target); | ||
if (targetFunction['__symbolic'] == 'function') { | ||
if (calling.get(targetFunction)) { | ||
if (targetFunction && targetFunction['__symbolic'] == 'function') { | ||
if (calling.get(functionSymbol)) { | ||
throw new Error('Recursion not supported'); | ||
} | ||
calling.set(targetFunction, true); | ||
var value_1 = targetFunction['value']; | ||
if (value_1) { | ||
// Determine the arguments | ||
var args = (expression['arguments'] || []).map(function (arg) { return simplify(arg); }); | ||
var parameters = targetFunction['parameters']; | ||
var functionScope = BindingScope.build(); | ||
for (var i = 0; i < parameters.length; i++) { | ||
functionScope.define(parameters[i], args[i]); | ||
calling.set(functionSymbol, true); | ||
try { | ||
var value_1 = targetFunction['value']; | ||
if (value_1 && (depth != 0 || value_1.__symbolic != 'error')) { | ||
// Determine the arguments | ||
var args = (expression['arguments'] || []).map(function (arg) { return simplify(arg); }); | ||
var parameters = targetFunction['parameters']; | ||
var defaults = targetFunction.defaults; | ||
if (defaults && defaults.length > args.length) { | ||
args.push.apply(args, defaults.slice(args.length).map(function (value) { return simplify(value); })); | ||
} | ||
var functionScope = BindingScope.build(); | ||
for (var i = 0; i < parameters.length; i++) { | ||
functionScope.define(parameters[i], args[i]); | ||
} | ||
var oldScope = scope; | ||
var result_1; | ||
try { | ||
scope = functionScope.done(); | ||
result_1 = simplifyInContext(functionSymbol, value_1, depth + 1); | ||
} | ||
finally { | ||
scope = oldScope; | ||
} | ||
return result_1; | ||
} | ||
var oldScope = scope; | ||
var result_1; | ||
try { | ||
scope = functionScope.done(); | ||
result_1 = simplify(value_1); | ||
} | ||
finally { | ||
scope = oldScope; | ||
} | ||
return result_1; | ||
} | ||
calling.delete(targetFunction); | ||
finally { | ||
calling.delete(functionSymbol); | ||
} | ||
} | ||
@@ -248,3 +282,3 @@ } | ||
} | ||
return simplify({ __symbolic: 'error', message: 'Function call not supported', context: context }); | ||
return simplify({ __symbolic: 'error', message: 'Function call not supported', context: callContext }); | ||
} | ||
@@ -332,2 +366,6 @@ function simplify(expression) { | ||
return null; | ||
case 'if': | ||
var condition = simplify(expression['condition']); | ||
return condition ? simplify(expression['thenExpression']) : | ||
simplify(expression['elseExpression']); | ||
case 'pre': | ||
@@ -356,5 +394,15 @@ var operand = simplify(expression['operand']); | ||
var selectTarget = simplify(expression['expression']); | ||
if (selectTarget instanceof StaticSymbol) { | ||
// Access to a static instance variable | ||
var declarationValue_1 = resolveReferenceValue(selectTarget); | ||
if (declarationValue_1 && declarationValue_1.statics) { | ||
selectTarget = declarationValue_1.statics; | ||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
var member = simplify(expression['member']); | ||
if (selectTarget && isPrimitive(member)) | ||
return selectTarget[member]; | ||
return simplify(selectTarget[member]); | ||
return null; | ||
@@ -369,8 +417,7 @@ case 'reference': | ||
} | ||
staticSymbol = resolveReference(expression); | ||
staticSymbol = resolveReference(context, expression); | ||
var result_3 = staticSymbol; | ||
var moduleMetadata = _this.getModuleMetadata(staticSymbol.filePath); | ||
var declarationValue = moduleMetadata ? moduleMetadata['metadata'][staticSymbol.name] : null; | ||
var declarationValue = resolveReferenceValue(result_3); | ||
if (declarationValue) { | ||
if (isOpaqueToken(declarationValue)) { | ||
if (isOpaqueToken(staticSymbol, declarationValue)) { | ||
// If the referenced symbol is initalized by a new OpaqueToken we can keep the | ||
@@ -386,3 +433,3 @@ // reference to the symbol. | ||
case 'function': | ||
return expression; | ||
return context; | ||
case 'new': | ||
@@ -412,3 +459,3 @@ case 'call': | ||
message = | ||
message + " (position " + expression['line'] + ":" + expression['character'] + " in the original .ts file)"; | ||
message + " (position " + (expression['line'] + 1) + ":" + (expression['character'] + 1) + " in the original .ts file)"; | ||
} | ||
@@ -490,2 +537,6 @@ throw new Error(message); | ||
'unction calls are not supported. Consider replacing the function or lambda with a reference to an exported function'; | ||
case 'Reference to a local symbol': | ||
if (error.context && error.context.name) { | ||
return "Reference to a local (non-exported) symbol '" + error.context.name + "'. Consider exporting the symbol"; | ||
} | ||
} | ||
@@ -492,0 +543,0 @@ return error.message; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
136125
31
1610