From c493d88405f6b37349a5708092b98b2b8ebe6b79 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Thu, 28 Apr 2016 21:54:02 -0700 Subject: [PATCH] chore(compiler): refactoring for offline compiler cli - pass a baseUrl for asset resolution from static symbols - fixes in StaticReflector to work with a path-aware host see #7483 --- .../angular2/src/compiler/compile_metadata.ts | 14 +- .../src/compiler/directive_normalizer.ts | 6 +- .../src/compiler/metadata_resolver.ts | 24 ++- .../angular2/src/compiler/static_reflector.ts | 174 +++++++-------- .../compiler/view_compiler/event_binder.ts | 3 +- .../test/compiler/compile_metadata_spec.ts | 3 +- .../compiler/directive_normalizer_spec.ts | 203 ++++++++++++------ .../test/compiler/metadata_resolver_spec.ts | 4 +- .../test/compiler/offline_compiler_util.ts | 3 +- .../test/compiler/static_reflector_spec.ts | 193 +++++++++-------- .../common/type_metadata_reader.dart | 10 +- 11 files changed, 357 insertions(+), 280 deletions(-) diff --git a/modules/angular2/src/compiler/compile_metadata.ts b/modules/angular2/src/compiler/compile_metadata.ts index 36d63f7514..ed8f10c1d5 100644 --- a/modules/angular2/src/compiler/compile_metadata.ts +++ b/modules/angular2/src/compiler/compile_metadata.ts @@ -468,13 +468,16 @@ export class CompileTemplateMetadata { styles: string[]; styleUrls: string[]; ngContentSelectors: string[]; - constructor({encapsulation, template, templateUrl, styles, styleUrls, ngContentSelectors}: { + baseUrl: string; + constructor({encapsulation, template, templateUrl, styles, styleUrls, ngContentSelectors, + baseUrl}: { encapsulation?: ViewEncapsulation, template?: string, templateUrl?: string, styles?: string[], styleUrls?: string[], - ngContentSelectors?: string[] + ngContentSelectors?: string[], + baseUrl?: string } = {}) { this.encapsulation = isPresent(encapsulation) ? encapsulation : ViewEncapsulation.Emulated; this.template = template; @@ -482,6 +485,7 @@ export class CompileTemplateMetadata { this.styles = isPresent(styles) ? styles : []; this.styleUrls = isPresent(styleUrls) ? styleUrls : []; this.ngContentSelectors = isPresent(ngContentSelectors) ? ngContentSelectors : []; + this.baseUrl = baseUrl; } static fromJson(data: {[key: string]: any}): CompileTemplateMetadata { @@ -493,7 +497,8 @@ export class CompileTemplateMetadata { templateUrl: data['templateUrl'], styles: data['styles'], styleUrls: data['styleUrls'], - ngContentSelectors: data['ngContentSelectors'] + ngContentSelectors: data['ngContentSelectors'], + baseUrl: data['baseUrl'] }); } @@ -505,7 +510,8 @@ export class CompileTemplateMetadata { 'templateUrl': this.templateUrl, 'styles': this.styles, 'styleUrls': this.styleUrls, - 'ngContentSelectors': this.ngContentSelectors + 'ngContentSelectors': this.ngContentSelectors, + 'baseUrl': this.baseUrl }; } } diff --git a/modules/angular2/src/compiler/directive_normalizer.ts b/modules/angular2/src/compiler/directive_normalizer.ts index 5ffabda9ac..5c5f749f03 100644 --- a/modules/angular2/src/compiler/directive_normalizer.ts +++ b/modules/angular2/src/compiler/directive_normalizer.ts @@ -66,9 +66,9 @@ export class DirectiveNormalizer { template: CompileTemplateMetadata): Promise { if (isPresent(template.template)) { return PromiseWrapper.resolve(this.normalizeLoadedTemplate( - directiveType, template, template.template, directiveType.moduleUrl)); + directiveType, template, template.template, template.baseUrl)); } else if (isPresent(template.templateUrl)) { - var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl); + var sourceAbsUrl = this._urlResolver.resolve(template.baseUrl, template.templateUrl); return this._xhr.get(sourceAbsUrl) .then(templateContent => this.normalizeLoadedTemplate(directiveType, template, templateContent, sourceAbsUrl)); @@ -93,7 +93,7 @@ export class DirectiveNormalizer { visitor.styleUrls.filter(isStyleUrlResolvable) .map(url => this._urlResolver.resolve(templateAbsUrl, url)) .concat(templateMeta.styleUrls.filter(isStyleUrlResolvable) - .map(url => this._urlResolver.resolve(directiveType.moduleUrl, url))); + .map(url => this._urlResolver.resolve(templateMeta.baseUrl, url))); var allResolvedStyles = allStyles.map(style => { var styleWithImports = extractStyleUrls(this._urlResolver, templateAbsUrl, style); diff --git a/modules/angular2/src/compiler/metadata_resolver.ts b/modules/angular2/src/compiler/metadata_resolver.ts index c4ffca214f..e71184f9c5 100644 --- a/modules/angular2/src/compiler/metadata_resolver.ts +++ b/modules/angular2/src/compiler/metadata_resolver.ts @@ -76,7 +76,6 @@ export class CompileMetadataResolver { var meta = this._directiveCache.get(directiveType); if (isBlank(meta)) { var dirMeta = this._directiveResolver.resolve(directiveType); - var moduleUrl = staticTypeModuleUrl(directiveType); var templateMeta = null; var changeDetectionStrategy = null; var viewProviders = []; @@ -84,7 +83,6 @@ export class CompileMetadataResolver { if (dirMeta instanceof md.ComponentMetadata) { assertArrayOfStrings('styles', dirMeta.styles); var cmpMeta = dirMeta; - moduleUrl = calcModuleUrl(this._reflector, directiveType, cmpMeta); var viewMeta = this._viewResolver.resolve(directiveType); assertArrayOfStrings('styles', viewMeta.styles); templateMeta = new cpl.CompileTemplateMetadata({ @@ -92,7 +90,8 @@ export class CompileMetadataResolver { template: viewMeta.template, templateUrl: viewMeta.templateUrl, styles: viewMeta.styles, - styleUrls: viewMeta.styleUrls + styleUrls: viewMeta.styleUrls, + baseUrl: calcTemplateBaseUrl(this._reflector, directiveType, cmpMeta) }); changeDetectionStrategy = cmpMeta.changeDetection; if (isPresent(dirMeta.viewProviders)) { @@ -114,7 +113,7 @@ export class CompileMetadataResolver { selector: dirMeta.selector, exportAs: dirMeta.exportAs, isComponent: isPresent(templateMeta), - type: this.getTypeMetadata(directiveType, moduleUrl), + type: this.getTypeMetadata(directiveType, staticTypeModuleUrl(directiveType)), template: templateMeta, changeDetection: changeDetectionStrategy, inputs: dirMeta.inputs, @@ -399,14 +398,19 @@ function staticTypeModuleUrl(value: any): string { return isStaticType(value) ? value['moduleId'] : null; } -function calcModuleUrl(reflector: ReflectorReader, type: Type, - cmpMetadata: md.ComponentMetadata): string { - var moduleId = cmpMetadata.moduleId; - if (isPresent(moduleId)) { + +function calcTemplateBaseUrl(reflector: ReflectorReader, type: any, + cmpMetadata: md.ComponentMetadata): string { + if (isStaticType(type)) { + return type['filePath']; + } + + if (isPresent(cmpMetadata.moduleId)) { + var moduleId = cmpMetadata.moduleId; var scheme = getUrlScheme(moduleId); return isPresent(scheme) && scheme.length > 0 ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`; - } else { - return reflector.importUri(type); } + + return reflector.importUri(type); } diff --git a/modules/angular2/src/compiler/static_reflector.ts b/modules/angular2/src/compiler/static_reflector.ts index 23b8001574..1e97b81ece 100644 --- a/modules/angular2/src/compiler/static_reflector.ts +++ b/modules/angular2/src/compiler/static_reflector.ts @@ -19,7 +19,6 @@ import { HostListenerMetadata, OutputMetadata, PipeMetadata, - ViewMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, @@ -37,6 +36,10 @@ import { InjectMetadata } from "angular2/src/core/di/metadata"; +export class ModuleContext { + constructor(public moduleId: string, public filePath: string) {} +} + /** * The host of the static resolver is expected to be able to provide module metadata in the form of * ModuleMetadata. Angular 2 CLI will produce this metadata for a module whenever a .d.ts files is @@ -53,14 +56,13 @@ export interface StaticReflectorHost { getMetadataFor(modulePath: string): {[key: string]: any}; /** - * Resolve a module from an import statement form to an absolute path. - * @param moduleName the location imported from + * Resolve a symbol from an import statement form, to the file where it is declared. + * @param module the location imported from * @param containingFile for relative imports, the path of the file containing the import */ - resolveModule(moduleName: string, containingFile?: string): string; + findDeclaration(modulePath: string, symbolName: string, containingFile?: string): StaticSymbol; - findDeclaration(modulePath: string, - symbolName: string): {declarationPath: string, declaredName: string}; + getStaticSymbol(moduleId: string, declarationFile: string, name: string): StaticSymbol; } /** @@ -68,8 +70,8 @@ export interface StaticReflectorHost { * * This token is unique for a moduleId and name and can be used as a hash table key. */ -export class StaticType { - constructor(public moduleId: string, public name: string) {} +export class StaticSymbol { + constructor(public moduleId: string, public filePath: string, public name: string) {} } /** @@ -77,40 +79,23 @@ export class StaticType { * templates statically. */ export class StaticReflector implements ReflectorReader { - private typeCache = new Map(); - private annotationCache = new Map(); - private propertyCache = new Map(); - private parameterCache = new Map(); + private annotationCache = new Map(); + private propertyCache = new Map(); + private parameterCache = new Map(); private metadataCache = new Map(); - private conversionMap = new Map any>(); + private conversionMap = + new Map any>(); constructor(private host: StaticReflectorHost) { this.initializeConversionMap(); } - importUri(typeOrFunc: any): string { return (typeOrFunc).moduleId; } + importUri(typeOrFunc: any): string { return (typeOrFunc).filePath; } - /** - * getStaticType produces a Type whose metadata is known but whose implementation is not loaded. - * All types passed to the StaticResolver should be pseudo-types returned by this method. - * - * @param moduleId the module identifier as an absolute path. - * @param name the name of the type. - */ - public getStaticType(moduleId: string, name: string): StaticType { - let key = `"${moduleId}".${name}`; - let result = this.typeCache.get(key); - if (!isPresent(result)) { - result = new StaticType(moduleId, name); - this.typeCache.set(key, result); - } - return result; - } - - public annotations(type: StaticType): any[] { + public annotations(type: StaticSymbol): any[] { let annotations = this.annotationCache.get(type); if (!isPresent(annotations)) { let classMetadata = this.getTypeMetadata(type); if (isPresent(classMetadata['decorators'])) { - annotations = this.simplify(type.moduleId, classMetadata['decorators'], false); + annotations = this.simplify(type, classMetadata['decorators'], false); } else { annotations = []; } @@ -119,7 +104,7 @@ export class StaticReflector implements ReflectorReader { return annotations; } - public propMetadata(type: StaticType): {[key: string]: any} { + public propMetadata(type: StaticSymbol): {[key: string]: any} { let propMetadata = this.propertyCache.get(type); if (!isPresent(propMetadata)) { let classMetadata = this.getTypeMetadata(type); @@ -127,7 +112,7 @@ export class StaticReflector implements ReflectorReader { propMetadata = mapStringMap(members, (propData, propName) => { let prop = (propData).find(a => a['__symbolic'] == 'property'); if (isPresent(prop) && isPresent(prop['decorators'])) { - return this.simplify(type.moduleId, prop['decorators'], false); + return this.simplify(type, prop['decorators'], false); } else { return []; } @@ -137,7 +122,7 @@ export class StaticReflector implements ReflectorReader { return propMetadata; } - public parameters(type: StaticType): any[] { + public parameters(type: StaticSymbol): any[] { let parameters = this.parameterCache.get(type); if (!isPresent(parameters)) { let classMetadata = this.getTypeMetadata(type); @@ -145,9 +130,8 @@ export class StaticReflector implements ReflectorReader { let ctorData = isPresent(members) ? members['__ctor__'] : null; if (isPresent(ctorData)) { let ctor = (ctorData).find(a => a['__symbolic'] == 'constructor'); - let parameterTypes = this.simplify(type.moduleId, ctor['parameters'], false); - let parameterDecorators = - this.simplify(type.moduleId, ctor['parameterDecorators'], false); + let parameterTypes = this.simplify(type, ctor['parameters'], false); + let parameterDecorators = this.simplify(type, ctor['parameterDecorators'], false); parameters = []; ListWrapper.forEachWithIndex(parameterTypes, (paramType, index) => { @@ -170,9 +154,9 @@ export class StaticReflector implements ReflectorReader { return parameters; } - private registerDecoratorOrConstructor(type: StaticType, ctor: any, + private registerDecoratorOrConstructor(type: StaticSymbol, ctor: any, crossModuleProps: any[] = CONST_EXPR([])): void { - this.conversionMap.set(type, (moduleContext: string, args: any[]) => { + this.conversionMap.set(type, (moduleContext: ModuleContext, args: any[]) => { let argValues = []; ListWrapper.forEachWithIndex(args, (arg, index) => { let argValue; @@ -190,62 +174,67 @@ export class StaticReflector implements ReflectorReader { } private initializeConversionMap(): void { - let coreDecorators = this.host.resolveModule('angular2/src/core/metadata'); - let diDecorators = this.host.resolveModule('angular2/src/core/di/decorators'); - let diMetadata = this.host.resolveModule('angular2/src/core/di/metadata'); + let coreDecorators = 'angular2/src/core/metadata'; + let diDecorators = 'angular2/src/core/di/decorators'; + let diMetadata = 'angular2/src/core/di/metadata'; + let provider = 'angular2/src/core/di/provider'; + this.registerDecoratorOrConstructor(this.host.findDeclaration(provider, 'Provider'), Provider); - let provider = this.host.resolveModule('angular2/src/core/di/provider'); - this.registerDecoratorOrConstructor(this.getStaticType(provider, 'Provider'), Provider); - - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Host'), HostMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Injectable'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'Host'), + HostMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'Injectable'), InjectableMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Self'), SelfMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'SkipSelf'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'Self'), + SelfMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'SkipSelf'), SkipSelfMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Inject'), InjectMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Optional'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'Inject'), + InjectMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(diDecorators, 'Optional'), OptionalMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Attribute'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Attribute'), AttributeMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Query'), QueryMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewQuery'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Query'), + QueryMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'ViewQuery'), ViewQueryMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ContentChild'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'ContentChild'), ContentChildMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ContentChildren'), - ContentChildrenMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewChild'), + this.registerDecoratorOrConstructor( + this.host.findDeclaration(coreDecorators, 'ContentChildren'), ContentChildrenMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'ViewChild'), ViewChildMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewChildren'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'ViewChildren'), ViewChildrenMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Input'), InputMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Output'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Input'), + InputMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Output'), OutputMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Pipe'), PipeMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'HostBinding'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Pipe'), + PipeMetadata); + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'HostBinding'), HostBindingMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'HostListener'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'HostListener'), HostListenerMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Directive'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Directive'), DirectiveMetadata, ['bindings', 'providers']); - this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Component'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(coreDecorators, 'Component'), ComponentMetadata, ['bindings', 'providers', 'directives', 'pipes']); // Note: Some metadata classes can be used directly with Provider.deps. - this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'HostMetadata'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diMetadata, 'HostMetadata'), HostMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'SelfMetadata'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diMetadata, 'SelfMetadata'), SelfMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'SkipSelfMetadata'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diMetadata, 'SkipSelfMetadata'), SkipSelfMetadata); - this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'OptionalMetadata'), + this.registerDecoratorOrConstructor(this.host.findDeclaration(diMetadata, 'OptionalMetadata'), OptionalMetadata); } /** @internal */ - public simplify(moduleContext: string, value: any, crossModules: boolean): any { + public simplify(moduleContext: ModuleContext, value: any, crossModules: boolean): any { let _this = this; function simplify(expression: any): any { @@ -261,6 +250,7 @@ export class StaticReflector implements ReflectorReader { } if (isPresent(expression)) { if (isPresent(expression['__symbolic'])) { + let staticSymbol; switch (expression['__symbolic']) { case "binop": let left = simplify(expression['left']); @@ -332,35 +322,34 @@ export class StaticReflector implements ReflectorReader { if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member]; return null; case "reference": - let referenceModuleName; - let declarationPath = moduleContext; - let declaredName = expression['name']; if (isPresent(expression['module'])) { - referenceModuleName = _this.host.resolveModule(expression['module'], moduleContext); - let decl = _this.host.findDeclaration(referenceModuleName, expression['name']); - declarationPath = decl['declarationPath']; - declaredName = decl['declaredName']; + staticSymbol = _this.host.findDeclaration(expression['module'], expression['name'], + moduleContext.filePath); + } else { + staticSymbol = _this.host.getStaticSymbol( + moduleContext.moduleId, moduleContext.filePath, expression['name']); } let result; if (crossModules || isBlank(expression['module'])) { - let moduleMetadata = _this.getModuleMetadata(declarationPath); - let declarationValue = moduleMetadata['metadata'][declaredName]; + let moduleMetadata = _this.getModuleMetadata(staticSymbol.filePath); + let declarationValue = moduleMetadata['metadata'][staticSymbol.name]; if (isClassMetadata(declarationValue)) { - result = _this.getStaticType(declarationPath, declaredName); + result = staticSymbol; } else { - result = _this.simplify(declarationPath, declarationValue, crossModules); + const newModuleContext = + new ModuleContext(staticSymbol.moduleId, staticSymbol.filePath); + result = _this.simplify(newModuleContext, declarationValue, crossModules); } } else { - result = _this.getStaticType(declarationPath, declaredName); + result = staticSymbol; } return result; case "new": case "call": let target = expression['expression']; - let moduleId = _this.host.resolveModule(target['module'], moduleContext); - let decl = _this.host.findDeclaration(moduleId, target['name']); - let staticType = _this.getStaticType(decl['declarationPath'], decl['declaredName']); - let converter = _this.conversionMap.get(staticType); + staticSymbol = _this.host.findDeclaration(target['module'], target['name'], + moduleContext.filePath); + let converter = _this.conversionMap.get(staticSymbol); let args = expression['arguments']; if (isBlank(args)) { args = []; @@ -392,8 +381,11 @@ export class StaticReflector implements ReflectorReader { return moduleMetadata; } - private getTypeMetadata(type: StaticType): {[key: string]: any} { - let moduleMetadata = this.getModuleMetadata(type.moduleId); + private getTypeMetadata(type: StaticSymbol): {[key: string]: any} { + if (!(type instanceof StaticSymbol)) { + throw new Error('not static type'); + } + let moduleMetadata = this.getModuleMetadata(type.filePath); let result = moduleMetadata['metadata'][type.name]; if (!isPresent(result)) { result = {__symbolic: "class"}; diff --git a/modules/angular2/src/compiler/view_compiler/event_binder.ts b/modules/angular2/src/compiler/view_compiler/event_binder.ts index 4846ef18f6..90926b4946 100644 --- a/modules/angular2/src/compiler/view_compiler/event_binder.ts +++ b/modules/angular2/src/compiler/view_compiler/event_binder.ts @@ -87,7 +87,8 @@ export class CompileEventListener { [ new o.ReturnStatement( o.THIS_EXPR.callMethod(this._methodName, [EventHandlerVars.event])) - ], o.BOOL_TYPE) + ], + o.BOOL_TYPE) ]); if (isPresent(this.eventTarget)) { listenExpr = ViewProperties.renderer.callMethod( diff --git a/modules/angular2/test/compiler/compile_metadata_spec.ts b/modules/angular2/test/compiler/compile_metadata_spec.ts index 2a6009666f..9bf835532d 100644 --- a/modules/angular2/test/compiler/compile_metadata_spec.ts +++ b/modules/angular2/test/compiler/compile_metadata_spec.ts @@ -63,7 +63,8 @@ export function main() { templateUrl: 'someTemplateUrl', styles: ['someStyle'], styleUrls: ['someStyleUrl'], - ngContentSelectors: ['*'] + ngContentSelectors: ['*'], + baseUrl: 'someBaseUrl' }); fullDirectiveMeta = CompileDirectiveMetadata.create({ selector: 'someSelector', diff --git a/modules/angular2/test/compiler/directive_normalizer_spec.ts b/modules/angular2/test/compiler/directive_normalizer_spec.ts index da9d9c58f0..f6b51d2ec9 100644 --- a/modules/angular2/test/compiler/directive_normalizer_spec.ts +++ b/modules/angular2/test/compiler/directive_normalizer_spec.ts @@ -24,15 +24,10 @@ import {TEST_PROVIDERS} from './test_bindings'; export function main() { describe('DirectiveNormalizer', () => { var dirType: CompileTypeMetadata; - var dirTypeWithHttpUrl: CompileTypeMetadata; beforeEachProviders(() => TEST_PROVIDERS); - beforeEach(() => { - dirType = new CompileTypeMetadata({moduleUrl: 'package:some/module/a.js', name: 'SomeComp'}); - dirTypeWithHttpUrl = - new CompileTypeMetadata({moduleUrl: 'http://some/module/a.js', name: 'SomeComp'}); - }); + beforeEach(() => { dirType = new CompileTypeMetadata({name: 'SomeComp'}); }); describe('loadTemplate', () => { describe('inline template', () => { @@ -44,7 +39,8 @@ export function main() { template: 'a', templateUrl: null, styles: [], - styleUrls: ['test.css'] + styleUrls: ['test.css'], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.template).toEqual('a'); @@ -53,7 +49,7 @@ export function main() { }); })); - it('should resolve styles on the annotation against the moduleUrl', + it('should resolve styles on the annotation against the baseUrl', inject([AsyncTestCompleter, DirectiveNormalizer], (async, normalizer: DirectiveNormalizer) => { normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({ @@ -61,7 +57,8 @@ export function main() { template: '', templateUrl: null, styles: [], - styleUrls: ['test.css'] + styleUrls: ['test.css'], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.styleUrls).toEqual(['package:some/module/test.css']); @@ -69,7 +66,7 @@ export function main() { }); })); - it('should resolve styles in the template against the moduleUrl', + it('should resolve styles in the template against the baseUrl', inject([AsyncTestCompleter, DirectiveNormalizer], (async, normalizer: DirectiveNormalizer) => { normalizer.normalizeTemplate(dirType, new CompileTemplateMetadata({ @@ -77,7 +74,8 @@ export function main() { template: '', templateUrl: null, styles: [], - styleUrls: [] + styleUrls: [], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.styleUrls).toEqual(['package:some/module/test.css']); @@ -88,7 +86,7 @@ export function main() { describe('templateUrl', () => { - it('should load a template from a url that is resolved against moduleUrl', + it('should load a template from a url that is resolved against baseUrl', inject([AsyncTestCompleter, DirectiveNormalizer, XHR], (async, normalizer: DirectiveNormalizer, xhr: MockXHR) => { xhr.expect('package:some/module/sometplurl.html', 'a'); @@ -97,7 +95,8 @@ export function main() { template: null, templateUrl: 'sometplurl.html', styles: [], - styleUrls: ['test.css'] + styleUrls: ['test.css'], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.template).toEqual('a'); @@ -108,7 +107,7 @@ export function main() { xhr.flush(); })); - it('should resolve styles on the annotation against the moduleUrl', + it('should resolve styles on the annotation against the baseUrl', inject([AsyncTestCompleter, DirectiveNormalizer, XHR], (async, normalizer: DirectiveNormalizer, xhr: MockXHR) => { xhr.expect('package:some/module/tpl/sometplurl.html', ''); @@ -117,7 +116,8 @@ export function main() { template: null, templateUrl: 'tpl/sometplurl.html', styles: [], - styleUrls: ['test.css'] + styleUrls: ['test.css'], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.styleUrls).toEqual(['package:some/module/test.css']); @@ -136,7 +136,8 @@ export function main() { template: null, templateUrl: 'tpl/sometplurl.html', styles: [], - styleUrls: [] + styleUrls: [], + baseUrl: 'package:some/module/a.js' })) .then((template: CompileTemplateMetadata) => { expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']); @@ -162,36 +163,50 @@ export function main() { inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { var viewEncapsulation = ViewEncapsulation.Native; - var template = normalizer.normalizeLoadedTemplate( - dirType, new CompileTemplateMetadata( - {encapsulation: viewEncapsulation, styles: [], styleUrls: []}), - '', 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: viewEncapsulation, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', 'package:some/module/'); expect(template.encapsulation).toBe(viewEncapsulation); })); it('should keep the template as html', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), 'a', - 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + 'a', 'package:some/module/'); expect(template.template).toEqual('a') })); it('should collect ngContent', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), - '', 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', + 'package:some/module/'); expect(template.ngContentSelectors).toEqual(['a']); })); it('should normalize ngContent wildcard selector', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), + dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), '', 'package:some/module/'); expect(template.ngContentSelectors).toEqual(['*', '*', '*']); @@ -199,64 +214,91 @@ export function main() { it('should collect top level styles in the template', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), - '', 'package:some/module/'); + var template = + normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', 'package:some/module/'); expect(template.styles).toEqual(['a']); })); it('should collect styles inside in elements', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), - '
', 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '
', + 'package:some/module/'); expect(template.styles).toEqual(['a']); })); it('should collect styleUrls in the template', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), - '', 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', + 'package:some/module/'); expect(template.styleUrls).toEqual(['package:some/module/aUrl']); })); it('should collect styleUrls in elements', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), + dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), '
', 'package:some/module/'); expect(template.styleUrls).toEqual(['package:some/module/aUrl']); })); it('should ignore link elements with non stylesheet rel attribute', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), - '', 'package:some/module/'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', + 'package:some/module/'); expect(template.styleUrls).toEqual([]); })); it('should ignore link elements with absolute urls but non package: scheme', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), + dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), '', 'package:some/module/'); expect(template.styleUrls).toEqual([]); })); it('should extract @import style urls into styleAbsUrl', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, new CompileTemplateMetadata( - {encapsulation: null, styles: ['@import "test.css";'], styleUrls: []}), - '', 'package:some/module/id'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: ['@import "test.css";'], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', 'package:some/module/id'); expect(template.styles).toEqual(['']); expect(template.styleUrls).toEqual(['package:some/module/test.css']); })); @@ -267,7 +309,8 @@ export function main() { dirType, new CompileTemplateMetadata({ encapsulation: null, styles: ['.foo{background-image: url(\'double.jpg\');'], - styleUrls: [] + styleUrls: [], + baseUrl: 'package:some/module/a.js' }), '', 'package:some/module/id'); expect(template.styles).toEqual(['.foo{background-image: url(\'double.jpg\');']); @@ -275,38 +318,52 @@ export function main() { it('should resolve relative style urls in styleUrls', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, new CompileTemplateMetadata( - {encapsulation: null, styles: [], styleUrls: ['test.css']}), - '', 'package:some/module/id'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: ['test.css'], + baseUrl: 'package:some/module/a.js' + }), + '', 'package:some/module/id'); expect(template.styles).toEqual([]); expect(template.styleUrls).toEqual(['package:some/module/test.css']); })); it('should resolve relative style urls in styleUrls with http directive url', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirTypeWithHttpUrl, new CompileTemplateMetadata( - {encapsulation: null, styles: [], styleUrls: ['test.css']}), - '', 'http://some/module/id'); + var template = normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: ['test.css'], + baseUrl: 'http://some/module/a.js' + }), + '', 'http://some/module/id'); expect(template.styles).toEqual([]); expect(template.styleUrls).toEqual(['http://some/module/test.css']); })); it('should normalize ViewEncapsulation.Emulated to ViewEncapsulation.None if there are no styles nor stylesheets', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { - var template = normalizer.normalizeLoadedTemplate( - dirType, new CompileTemplateMetadata( - {encapsulation: ViewEncapsulation.Emulated, styles: [], styleUrls: []}), - '', 'package:some/module/id'); + var template = + normalizer.normalizeLoadedTemplate(dirType, new CompileTemplateMetadata({ + encapsulation: ViewEncapsulation.Emulated, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), + '', 'package:some/module/id'); expect(template.encapsulation).toEqual(ViewEncapsulation.None); })); it('should ignore ng-content in elements with ngNonBindable', inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => { var template = normalizer.normalizeLoadedTemplate( - dirType, - new CompileTemplateMetadata({encapsulation: null, styles: [], styleUrls: []}), + dirType, new CompileTemplateMetadata({ + encapsulation: null, + styles: [], + styleUrls: [], + baseUrl: 'package:some/module/a.js' + }), '
', 'package:some/module/'); expect(template.ngContentSelectors).toEqual([]); @@ -315,8 +372,12 @@ export function main() { it('should still collect ', 'package:some/module/'); expect(template.styles).toEqual(['div {color:red}']); })); diff --git a/modules/angular2/test/compiler/metadata_resolver_spec.ts b/modules/angular2/test/compiler/metadata_resolver_spec.ts index a9efa58137..381afd7073 100644 --- a/modules/angular2/test/compiler/metadata_resolver_spec.ts +++ b/modules/angular2/test/compiler/metadata_resolver_spec.ts @@ -51,7 +51,6 @@ export function main() { expect(meta.isComponent).toBe(true); expect(meta.type.runtime).toBe(ComponentWithEverything); expect(meta.type.name).toEqual(stringify(ComponentWithEverything)); - expect(meta.type.moduleUrl).toEqual(`package:someModuleId${MODULE_SUFFIX}`); expect(meta.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES); expect(meta.changeDetection).toBe(ChangeDetectionStrategy.CheckAlways); expect(meta.inputs).toEqual({'someProp': 'someProp'}); @@ -64,12 +63,13 @@ export function main() { expect(meta.template.styleUrls).toEqual(['someStyleUrl']); expect(meta.template.template).toEqual('someTemplate'); expect(meta.template.templateUrl).toEqual('someTemplateUrl'); + expect(meta.template.baseUrl).toEqual(`package:someModuleId${MODULE_SUFFIX}`); })); it('should use the moduleUrl from the reflector if none is given', inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => { var value: string = - resolver.getDirectiveMetadata(ComponentWithoutModuleId).type.moduleUrl; + resolver.getDirectiveMetadata(ComponentWithoutModuleId).template.baseUrl; var expectedEndValue = IS_DART ? 'test/compiler/metadata_resolver_spec.dart' : './ComponentWithoutModuleId'; expect(value.endsWith(expectedEndValue)).toBe(true); diff --git a/modules/angular2/test/compiler/offline_compiler_util.ts b/modules/angular2/test/compiler/offline_compiler_util.ts index 666258c354..cbf2e05f34 100644 --- a/modules/angular2/test/compiler/offline_compiler_util.ts +++ b/modules/angular2/test/compiler/offline_compiler_util.ts @@ -39,7 +39,8 @@ export var compAMetadata = CompileDirectiveMetadata.create({ template: new CompileTemplateMetadata({ templateUrl: './offline_compiler_compa.html', styles: ['.redStyle { color: red; }'], - styleUrls: ['./offline_compiler_compa.css'] + styleUrls: ['./offline_compiler_compa.css'], + baseUrl: THIS_MODULE_URL, }) }); diff --git a/modules/angular2/test/compiler/static_reflector_spec.ts b/modules/angular2/test/compiler/static_reflector_spec.ts index d6e3869aa4..c1e0f8884f 100644 --- a/modules/angular2/test/compiler/static_reflector_spec.ts +++ b/modules/angular2/test/compiler/static_reflector_spec.ts @@ -1,13 +1,19 @@ import {describe, it, iit, expect, ddescribe, beforeEach} from 'angular2/testing_internal'; -import {IS_DART} from 'angular2/src/facade/lang'; +import {IS_DART, isBlank} from 'angular2/src/facade/lang'; import {ListWrapper} from 'angular2/src/facade/collection'; -import {StaticReflector, StaticReflectorHost} from 'angular2/src/compiler/static_reflector'; +import { + StaticReflector, + StaticReflectorHost, + StaticSymbol, + ModuleContext +} from 'angular2/src/compiler/static_reflector'; export function main() { // Static reflector is not supported in Dart // as we use reflection to create objects. if (IS_DART) return; + let noContext = new ModuleContext('', ''); describe('StaticReflector', () => { let host: StaticReflectorHost; @@ -18,17 +24,16 @@ export function main() { reflector = new StaticReflector(host); }); - function singleModuleSimplify(moduleContext: string, value: any) { + function singleModuleSimplify(moduleContext: ModuleContext, value: any) { return reflector.simplify(moduleContext, value, false); } - function crossModuleSimplify(moduleContext: string, value: any) { + function crossModuleSimplify(moduleContext: ModuleContext, value: any) { return reflector.simplify(moduleContext, value, true); } it('should get annotations for NgFor', () => { - let NgFor = reflector.getStaticType( - host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor'); + let NgFor = host.findDeclaration('angular2/src/common/directives/ng_for', 'NgFor'); let annotations = reflector.annotations(NgFor); expect(annotations.length).toEqual(1); let annotation = annotations[0]; @@ -38,18 +43,15 @@ export function main() { }); it('should get constructor for NgFor', () => { - let NgFor = reflector.getStaticType( - host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor'); - let ViewContainerRef = reflector.getStaticType( - host.resolveModule('angular2/src/core/linker/view_container_ref'), 'ViewContainerRef'); - let TemplateRef = reflector.getStaticType( - host.resolveModule('angular2/src/core/linker/template_ref'), 'TemplateRef'); - let IterableDiffers = reflector.getStaticType( - host.resolveModule('angular2/src/core/change_detection/differs/iterable_differs'), - 'IterableDiffers'); - let ChangeDetectorRef = reflector.getStaticType( - host.resolveModule('angular2/src/core/change_detection/change_detector_ref'), - 'ChangeDetectorRef'); + let NgFor = host.findDeclaration('angular2/src/common/directives/ng_for', 'NgFor'); + let ViewContainerRef = + host.findDeclaration('angular2/src/core/linker/view_container_ref', 'ViewContainerRef'); + let TemplateRef = + host.findDeclaration('angular2/src/core/linker/template_ref', 'TemplateRef'); + let IterableDiffers = host.findDeclaration( + 'angular2/src/core/change_detection/differs/iterable_differs', 'IterableDiffers'); + let ChangeDetectorRef = host.findDeclaration( + 'angular2/src/core/change_detection/change_detector_ref', 'ChangeDetectorRef'); let parameters = reflector.parameters(NgFor); expect(parameters) @@ -58,204 +60,208 @@ export function main() { it('should get annotations for HeroDetailComponent', () => { let HeroDetailComponent = - reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent'); + host.findDeclaration('src/app/hero-detail.component', 'HeroDetailComponent'); let annotations = reflector.annotations(HeroDetailComponent); expect(annotations.length).toEqual(1); let annotation = annotations[0]; expect(annotation.selector).toEqual('my-hero-detail'); expect(annotation.directives) - .toEqual([ - [ - reflector.getStaticType(host.resolveModule('angular2/src/common/directives/ng_for'), - 'NgFor') - ] - ]); + .toEqual([[host.findDeclaration('angular2/src/common/directives/ng_for', 'NgFor')]]); }); it('should get and empty annotation list for an unknown class', () => { - let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass'); + let UnknownClass = host.findDeclaration('src/app/app.component', 'UnknownClass'); let annotations = reflector.annotations(UnknownClass); expect(annotations).toEqual([]); }); it('should get propMetadata for HeroDetailComponent', () => { let HeroDetailComponent = - reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent'); + host.findDeclaration('src/app/hero-detail.component', 'HeroDetailComponent'); let props = reflector.propMetadata(HeroDetailComponent); expect(props['hero']).toBeTruthy(); }); it('should get an empty object from propMetadata for an unknown class', () => { - let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass'); + let UnknownClass = host.findDeclaration('src/app/app.component', 'UnknownClass'); let properties = reflector.propMetadata(UnknownClass); expect(properties).toEqual({}); }); it('should get empty parameters list for an unknown class ', () => { - let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass'); + let UnknownClass = host.findDeclaration('src/app/app.component', 'UnknownClass'); let parameters = reflector.parameters(UnknownClass); expect(parameters).toEqual([]); }); it('should simplify primitive into itself', () => { - expect(singleModuleSimplify('', 1)).toBe(1); - expect(singleModuleSimplify('', true)).toBe(true); - expect(singleModuleSimplify('', "some value")).toBe("some value"); + expect(singleModuleSimplify(noContext, 1)).toBe(1); + expect(singleModuleSimplify(noContext, true)).toBe(true); + expect(singleModuleSimplify(noContext, "some value")).toBe("some value"); }); it('should simplify an array into a copy of the array', - () => { expect(singleModuleSimplify('', [1, 2, 3])).toEqual([1, 2, 3]); }); + () => { expect(singleModuleSimplify(noContext, [1, 2, 3])).toEqual([1, 2, 3]); }); it('should simplify an object to a copy of the object', () => { let expr = {a: 1, b: 2, c: 3}; - expect(singleModuleSimplify('', expr)).toEqual(expr); + expect(singleModuleSimplify(noContext, expr)).toEqual(expr); }); it('should simplify &&', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: true}))).toBe(true); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: false}))).toBe(false); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: true}))).toBe(false); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: false}))).toBe(false); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&&', left: true, right: true}))).toBe(true); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&&', left: true, right: false}))).toBe(false); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&&', left: false, right: true}))).toBe(false); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&&', left: false, right: false}))).toBe(false); }); it('should simplify ||', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: true}))).toBe(true); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: false}))).toBe(true); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: true}))).toBe(true); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: false}))).toBe(false); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '||', left: true, right: true}))).toBe(true); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '||', left: true, right: false}))).toBe(true); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '||', left: false, right: true}))).toBe(true); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '||', left: false, right: false}))).toBe(false); }); it('should simplify &', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F}))).toBe(0x22 & 0x0F); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0}))).toBe(0x22 & 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F}))).toBe(0x22 & 0x0F); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0}))).toBe(0x22 & 0xF0); }); it('should simplify |', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0); }); it('should simplify ^', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0); }); it('should simplify ==', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0x22}))).toBe(0x22 == 0x22); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0}))).toBe(0x22 == 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0x22}))).toBe(0x22 == 0x22); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0}))).toBe(0x22 == 0xF0); }); it('should simplify !=', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22}))).toBe(0x22 != 0x22); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0}))).toBe(0x22 != 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22}))).toBe(0x22 != 0x22); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0}))).toBe(0x22 != 0xF0); }); it('should simplify ===', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0x22}))).toBe(0x22 === 0x22); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0}))).toBe(0x22 === 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0x22}))).toBe(0x22 === 0x22); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0}))).toBe(0x22 === 0xF0); }); it('should simplify !==', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22}))).toBe(0x22 !== 0x22); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0}))).toBe(0x22 !== 0xF0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22}))).toBe(0x22 !== 0x22); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0}))).toBe(0x22 !== 0xF0); }); it('should simplify >', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 1}))).toBe(1 > 1); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 0}))).toBe(1 > 0); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>', left: 0, right: 1}))).toBe(0 > 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>', left: 1, right: 1}))).toBe(1 > 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>', left: 1, right: 0}))).toBe(1 > 0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>', left: 0, right: 1}))).toBe(0 > 1); }); it('should simplify >=', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 1}))).toBe(1 >= 1); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 0}))).toBe(1 >= 0); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>=', left: 0, right: 1}))).toBe(0 >= 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>=', left: 1, right: 1}))).toBe(1 >= 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>=', left: 1, right: 0}))).toBe(1 >= 0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>=', left: 0, right: 1}))).toBe(0 >= 1); }); it('should simplify <=', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 1}))).toBe(1 <= 1); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 0}))).toBe(1 <= 0); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<=', left: 0, right: 1}))).toBe(0 <= 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<=', left: 1, right: 1}))).toBe(1 <= 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<=', left: 1, right: 0}))).toBe(1 <= 0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<=', left: 0, right: 1}))).toBe(0 <= 1); }); it('should simplify <', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 1}))).toBe(1 < 1); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 0}))).toBe(1 < 0); - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<', left: 0, right: 1}))).toBe(0 < 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<', left: 1, right: 1}))).toBe(1 < 1); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<', left: 1, right: 0}))).toBe(1 < 0); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<', left: 0, right: 1}))).toBe(0 < 1); }); it('should simplify <<', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<<', left: 0x55, right: 2}))).toBe(0x55 << 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '<<', left: 0x55, right: 2}))).toBe(0x55 << 2); }); it('should simplify >>', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>>', left: 0x55, right: 2}))).toBe(0x55 >> 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '>>', left: 0x55, right: 2}))).toBe(0x55 >> 2); }); it('should simplify +', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '+', left: 0x55, right: 2}))).toBe(0x55 + 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '+', left: 0x55, right: 2}))).toBe(0x55 + 2); }); it('should simplify -', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '-', left: 0x55, right: 2}))).toBe(0x55 - 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '-', left: 0x55, right: 2}))).toBe(0x55 - 2); }); it('should simplify *', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '*', left: 0x55, right: 2}))).toBe(0x55 * 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '*', left: 0x55, right: 2}))).toBe(0x55 * 2); }); it('should simplify /', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '/', left: 0x55, right: 2}))).toBe(0x55 / 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '/', left: 0x55, right: 2}))).toBe(0x55 / 2); }); it('should simplify %', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '%', left: 0x55, right: 2}))).toBe(0x55 % 2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'binop', operator: '%', left: 0x55, right: 2}))).toBe(0x55 % 2); }); it('should simplify prefix -', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2); }); it('should simplify prefix ~', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2); }); it('should simplify prefix !', () => { - expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '!', operand: true}))).toBe(!true); - expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '!', operand: false}))).toBe(!false); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'pre', operator: '!', operand: true}))).toBe(!true); + expect(singleModuleSimplify(noContext, ({ __symbolic: 'pre', operator: '!', operand: false}))).toBe(!false); }); it('should simplify an array index', () => { - expect(singleModuleSimplify('', ({__symbolic: "index", expression: [1, 2, 3], index: 2}))) + expect( + singleModuleSimplify(noContext, ({__symbolic: "index", expression: [1, 2, 3], index: 2}))) .toBe(3); }); it('should simplify an object index', () => { let expr = {__symbolic: "select", expression: {a: 1, b: 2, c: 3}, member: "b"}; - expect(singleModuleSimplify('', expr)).toBe(2); + expect(singleModuleSimplify(noContext, expr)).toBe(2); }); it('should simplify a module reference across modules', () => { - expect(crossModuleSimplify('/src/cases', + expect(crossModuleSimplify({moduleId: '', filePath: '/src/cases'}, ({__symbolic: "reference", module: "./extern", name: "s"}))) .toEqual("s"); }); it('should simplify a module reference without crossing modules', () => { - expect(singleModuleSimplify('/src/cases', + expect(singleModuleSimplify({moduleId: '', filePath: '/src/cases'}, ({__symbolic: "reference", module: "./extern", name: "s"}))) - .toEqual(reflector.getStaticType('/src/extern.d.ts', 's')); + .toEqual(host.getStaticSymbol('', '/src/extern.d.ts', 's')); }); }); } class MockReflectorHost implements StaticReflectorHost { - // In tests, assume that symbols are not re-exported - findDeclaration(modulePath: string, - symbolName: string): {declarationPath: string, declaredName: string} { - return {declarationPath: modulePath, declaredName: symbolName}; + private staticTypeCache = new Map(); + + getStaticSymbol(moduleId: string, declarationFile: string, name: string): StaticSymbol { + var cacheKey = `${declarationFile}:${name}`; + var result = this.staticTypeCache.get(cacheKey); + if (isBlank(result)) { + result = new StaticSymbol(moduleId, declarationFile, name); + this.staticTypeCache.set(cacheKey, result); + } + return result; } - resolveModule(moduleName: string, containingFile?: string): string { + + // In tests, assume that symbols are not re-exported + findDeclaration(modulePath: string, symbolName: string, containingFile: string): StaticSymbol { function splitPath(path: string): string[] { return path.split(/\/|\\/g); } function resolvePath(pathParts: string[]): string { @@ -286,10 +292,11 @@ class MockReflectorHost implements StaticReflectorHost { return result; } - if (moduleName.indexOf('.') === 0) { - return pathTo(containingFile, moduleName) + '.d.ts'; + if (modulePath.indexOf('.') === 0) { + return this.getStaticSymbol(`mod/${symbolName}`, pathTo(containingFile, modulePath) + '.d.ts', + symbolName); } - return '/tmp/' + moduleName + '.d.ts'; + return this.getStaticSymbol(`mod/${symbolName}`, '/tmp/' + modulePath + '.d.ts', symbolName); } getMetadataFor(moduleId: string): any { @@ -376,7 +383,7 @@ class MockReflectorHost implements StaticReflectorHost { {"metadata": {"IterableDiffers": {"__symbolic": "class"}}}, '/tmp/angular2/src/core/change_detection/change_detector_ref.d.ts': {"metadata": {"ChangeDetectorRef": {"__symbolic": "class"}}}, - '/src/app/hero-detail.component.ts': + '/tmp/src/app/hero-detail.component.d.ts': { "__symbolic": "module", "metadata": diff --git a/modules_dart/transform/lib/src/transform/common/type_metadata_reader.dart b/modules_dart/transform/lib/src/transform/common/type_metadata_reader.dart index 023daf2643..94a8d56bd8 100644 --- a/modules_dart/transform/lib/src/transform/common/type_metadata_reader.dart +++ b/modules_dart/transform/lib/src/transform/common/type_metadata_reader.dart @@ -398,7 +398,7 @@ class _DirectiveMetadataVisitor extends Object _hasMetadata = true; if (isComponent) { _cmpTemplate = - new _CompileTemplateMetadataVisitor().visitAnnotation(node); + new _CompileTemplateMetadataVisitor(toAssetUri(_assetId)).visitAnnotation(node); _validateTemplates(); } super.visitAnnotation(node); @@ -411,7 +411,7 @@ class _DirectiveMetadataVisitor extends Object '$node' /* source */); } _viewTemplate = - new _CompileTemplateMetadataVisitor().visitAnnotation(node); + new _CompileTemplateMetadataVisitor(toAssetUri(_assetId)).visitAnnotation(node); _validateTemplates(); } @@ -720,12 +720,15 @@ class _LifecycleHookVisitor extends SimpleAstVisitor> { /// [CompileTemplateMetadata]. class _CompileTemplateMetadataVisitor extends RecursiveAstVisitor { + String _baseUrl; ViewEncapsulation _encapsulation; String _template; String _templateUrl; List _styles; List _styleUrls; + _CompileTemplateMetadataVisitor(this._baseUrl); + @override CompileTemplateMetadata visitAnnotation(Annotation node) { super.visitAnnotation(node); @@ -743,7 +746,8 @@ class _CompileTemplateMetadataVisitor template: _template, templateUrl: _templateUrl, styles: _styles, - styleUrls: _styleUrls); + styleUrls: _styleUrls, + baseUrl: _baseUrl); } @override