refactor(compiler): make static reflector work
Also adjust `RuntimeMetadataResolver` to be able to use it. Also rename `RuntimeMetadataResolver` into `CompileMetadataResolver`. Closes #8313
This commit is contained in:
parent
769835e53e
commit
70b23ae2ca
@ -17,7 +17,7 @@ import {provide, Provider} from 'angular2/src/core/di';
|
|||||||
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
||||||
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
||||||
import {DirectiveNormalizer} from 'angular2/src/compiler/directive_normalizer';
|
import {DirectiveNormalizer} from 'angular2/src/compiler/directive_normalizer';
|
||||||
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
|
import {CompileMetadataResolver} from 'angular2/src/compiler/metadata_resolver';
|
||||||
import {StyleCompiler} from 'angular2/src/compiler/style_compiler';
|
import {StyleCompiler} from 'angular2/src/compiler/style_compiler';
|
||||||
import {ViewCompiler} from 'angular2/src/compiler/view_compiler/view_compiler';
|
import {ViewCompiler} from 'angular2/src/compiler/view_compiler/view_compiler';
|
||||||
import {CompilerConfig} from './config';
|
import {CompilerConfig} from './config';
|
||||||
@ -46,7 +46,7 @@ export const COMPILER_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
|||||||
HtmlParser,
|
HtmlParser,
|
||||||
TemplateParser,
|
TemplateParser,
|
||||||
DirectiveNormalizer,
|
DirectiveNormalizer,
|
||||||
RuntimeMetadataResolver,
|
CompileMetadataResolver,
|
||||||
DEFAULT_PACKAGE_URL_PROVIDER,
|
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||||
StyleCompiler,
|
StyleCompiler,
|
||||||
ViewCompiler,
|
ViewCompiler,
|
||||||
|
@ -6,12 +6,12 @@ import {
|
|||||||
isArray,
|
isArray,
|
||||||
stringify,
|
stringify,
|
||||||
isString,
|
isString,
|
||||||
|
isStringMap,
|
||||||
RegExpWrapper,
|
RegExpWrapper,
|
||||||
StringWrapper
|
StringWrapper
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {NoAnnotationError} from 'angular2/src/core/di/reflective_exceptions';
|
|
||||||
import * as cpl from './compile_metadata';
|
import * as cpl from './compile_metadata';
|
||||||
import * as md from 'angular2/src/core/metadata/directives';
|
import * as md from 'angular2/src/core/metadata/directives';
|
||||||
import * as dimd from 'angular2/src/core/metadata/di';
|
import * as dimd from 'angular2/src/core/metadata/di';
|
||||||
@ -28,20 +28,18 @@ import {MODULE_SUFFIX, sanitizeIdentifier} from './util';
|
|||||||
import {assertArrayOfStrings} from './assertions';
|
import {assertArrayOfStrings} from './assertions';
|
||||||
import {getUrlScheme} from 'angular2/src/compiler/url_resolver';
|
import {getUrlScheme} from 'angular2/src/compiler/url_resolver';
|
||||||
import {Provider} from 'angular2/src/core/di/provider';
|
import {Provider} from 'angular2/src/core/di/provider';
|
||||||
import {
|
|
||||||
constructDependencies,
|
|
||||||
ReflectiveDependency
|
|
||||||
} from 'angular2/src/core/di/reflective_provider';
|
|
||||||
import {
|
import {
|
||||||
OptionalMetadata,
|
OptionalMetadata,
|
||||||
SelfMetadata,
|
SelfMetadata,
|
||||||
HostMetadata,
|
HostMetadata,
|
||||||
SkipSelfMetadata
|
SkipSelfMetadata,
|
||||||
|
InjectMetadata
|
||||||
} from 'angular2/src/core/di/metadata';
|
} from 'angular2/src/core/di/metadata';
|
||||||
|
import {AttributeMetadata, QueryMetadata} from 'angular2/src/core/metadata/di';
|
||||||
import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader';
|
import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RuntimeMetadataResolver {
|
export class CompileMetadataResolver {
|
||||||
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
||||||
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
|
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
|
||||||
private _anonymousTypes = new Map<Object, number>();
|
private _anonymousTypes = new Map<Object, number>();
|
||||||
@ -78,7 +76,7 @@ export class RuntimeMetadataResolver {
|
|||||||
var meta = this._directiveCache.get(directiveType);
|
var meta = this._directiveCache.get(directiveType);
|
||||||
if (isBlank(meta)) {
|
if (isBlank(meta)) {
|
||||||
var dirMeta = this._directiveResolver.resolve(directiveType);
|
var dirMeta = this._directiveResolver.resolve(directiveType);
|
||||||
var moduleUrl = null;
|
var moduleUrl = staticTypeModuleUrl(directiveType);
|
||||||
var templateMeta = null;
|
var templateMeta = null;
|
||||||
var changeDetectionStrategy = null;
|
var changeDetectionStrategy = null;
|
||||||
var viewProviders = [];
|
var viewProviders = [];
|
||||||
@ -134,6 +132,21 @@ export class RuntimeMetadataResolver {
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param someType a symbol which may or may not be a directive type
|
||||||
|
* @returns {cpl.CompileDirectiveMetadata} if possible, otherwise null.
|
||||||
|
*/
|
||||||
|
maybeGetDirectiveMetadata(someType: Type): cpl.CompileDirectiveMetadata {
|
||||||
|
try {
|
||||||
|
return this.getDirectiveMetadata(someType);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.indexOf('No Directive annotation') !== -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getTypeMetadata(type: Type, moduleUrl: string): cpl.CompileTypeMetadata {
|
getTypeMetadata(type: Type, moduleUrl: string): cpl.CompileTypeMetadata {
|
||||||
return new cpl.CompileTypeMetadata({
|
return new cpl.CompileTypeMetadata({
|
||||||
name: this.sanitizeTokenName(type),
|
name: this.sanitizeTokenName(type),
|
||||||
@ -156,9 +169,8 @@ export class RuntimeMetadataResolver {
|
|||||||
var meta = this._pipeCache.get(pipeType);
|
var meta = this._pipeCache.get(pipeType);
|
||||||
if (isBlank(meta)) {
|
if (isBlank(meta)) {
|
||||||
var pipeMeta = this._pipeResolver.resolve(pipeType);
|
var pipeMeta = this._pipeResolver.resolve(pipeType);
|
||||||
var moduleUrl = this._reflector.importUri(pipeType);
|
|
||||||
meta = new cpl.CompilePipeMetadata({
|
meta = new cpl.CompilePipeMetadata({
|
||||||
type: this.getTypeMetadata(pipeType, moduleUrl),
|
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
|
||||||
name: pipeMeta.name,
|
name: pipeMeta.name,
|
||||||
pure: pipeMeta.pure,
|
pure: pipeMeta.pure,
|
||||||
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, pipeType)),
|
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, pipeType)),
|
||||||
@ -177,7 +189,6 @@ export class RuntimeMetadataResolver {
|
|||||||
`Unexpected directive value '${stringify(directives[i])}' on the View of component '${stringify(component)}'`);
|
`Unexpected directive value '${stringify(directives[i])}' on the View of component '${stringify(component)}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return directives.map(type => this.getDirectiveMetadata(type));
|
return directives.map(type => this.getDirectiveMetadata(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,41 +206,65 @@ export class RuntimeMetadataResolver {
|
|||||||
|
|
||||||
getDependenciesMetadata(typeOrFunc: Type | Function,
|
getDependenciesMetadata(typeOrFunc: Type | Function,
|
||||||
dependencies: any[]): cpl.CompileDiDependencyMetadata[] {
|
dependencies: any[]): cpl.CompileDiDependencyMetadata[] {
|
||||||
var deps: ReflectiveDependency[];
|
let params = isPresent(dependencies) ? dependencies : this._reflector.parameters(typeOrFunc);
|
||||||
try {
|
if (isBlank(params)) {
|
||||||
deps = constructDependencies(typeOrFunc, dependencies);
|
params = [];
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof NoAnnotationError) {
|
|
||||||
deps = [];
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return deps.map((dep) => {
|
return params.map((param) => {
|
||||||
var compileToken;
|
if (isBlank(param)) {
|
||||||
var p = <dimd.AttributeMetadata>dep.properties.find(p => p instanceof dimd.AttributeMetadata);
|
return null;
|
||||||
var isAttribute = false;
|
|
||||||
if (isPresent(p)) {
|
|
||||||
compileToken = this.getTokenMetadata(p.attributeName);
|
|
||||||
isAttribute = true;
|
|
||||||
} else {
|
|
||||||
compileToken = this.getTokenMetadata(dep.key.token);
|
|
||||||
}
|
}
|
||||||
var compileQuery = null;
|
let isAttribute = false;
|
||||||
var q = <dimd.QueryMetadata>dep.properties.find(p => p instanceof dimd.QueryMetadata);
|
let isHost = false;
|
||||||
if (isPresent(q)) {
|
let isSelf = false;
|
||||||
compileQuery = this.getQueryMetadata(q, null);
|
let isSkipSelf = false;
|
||||||
|
let isOptional = false;
|
||||||
|
let query: dimd.QueryMetadata = null;
|
||||||
|
let viewQuery: dimd.ViewQueryMetadata = null;
|
||||||
|
var token = null;
|
||||||
|
if (isArray(param)) {
|
||||||
|
(<any[]>param)
|
||||||
|
.forEach((paramEntry) => {
|
||||||
|
if (paramEntry instanceof HostMetadata) {
|
||||||
|
isHost = true;
|
||||||
|
} else if (paramEntry instanceof SelfMetadata) {
|
||||||
|
isSelf = true;
|
||||||
|
} else if (paramEntry instanceof SkipSelfMetadata) {
|
||||||
|
isSkipSelf = true;
|
||||||
|
} else if (paramEntry instanceof OptionalMetadata) {
|
||||||
|
isOptional = true;
|
||||||
|
} else if (paramEntry instanceof AttributeMetadata) {
|
||||||
|
isAttribute = true;
|
||||||
|
token = paramEntry.attributeName;
|
||||||
|
} else if (paramEntry instanceof QueryMetadata) {
|
||||||
|
if (paramEntry.isViewQuery) {
|
||||||
|
viewQuery = paramEntry;
|
||||||
|
} else {
|
||||||
|
query = paramEntry;
|
||||||
|
}
|
||||||
|
} else if (paramEntry instanceof InjectMetadata) {
|
||||||
|
token = paramEntry.token;
|
||||||
|
} else if (isValidType(paramEntry) && isBlank(token)) {
|
||||||
|
token = paramEntry;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
token = param;
|
||||||
|
}
|
||||||
|
if (isBlank(token)) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return new cpl.CompileDiDependencyMetadata({
|
return new cpl.CompileDiDependencyMetadata({
|
||||||
isAttribute: isAttribute,
|
isAttribute: isAttribute,
|
||||||
isHost: dep.upperBoundVisibility instanceof HostMetadata,
|
isHost: isHost,
|
||||||
isSelf: dep.upperBoundVisibility instanceof SelfMetadata,
|
isSelf: isSelf,
|
||||||
isSkipSelf: dep.lowerBoundVisibility instanceof SkipSelfMetadata,
|
isSkipSelf: isSkipSelf,
|
||||||
isOptional: dep.optional,
|
isOptional: isOptional,
|
||||||
query: isPresent(q) && !q.isViewQuery ? compileQuery : null,
|
query: isPresent(query) ? this.getQueryMetadata(query, null) : null,
|
||||||
viewQuery: isPresent(q) && q.isViewQuery ? compileQuery : null,
|
viewQuery: isPresent(viewQuery) ? this.getQueryMetadata(viewQuery, null) : null,
|
||||||
token: compileToken
|
token: this.getTokenMetadata(token)
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,8 +275,11 @@ export class RuntimeMetadataResolver {
|
|||||||
compileToken = new cpl.CompileTokenMetadata({value: token});
|
compileToken = new cpl.CompileTokenMetadata({value: token});
|
||||||
} else {
|
} else {
|
||||||
compileToken = new cpl.CompileTokenMetadata({
|
compileToken = new cpl.CompileTokenMetadata({
|
||||||
identifier: new cpl.CompileIdentifierMetadata(
|
identifier: new cpl.CompileIdentifierMetadata({
|
||||||
{runtime: token, name: this.sanitizeTokenName(token)})
|
runtime: token,
|
||||||
|
name: this.sanitizeTokenName(token),
|
||||||
|
moduleUrl: staticTypeModuleUrl(token)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return compileToken;
|
return compileToken;
|
||||||
@ -256,7 +294,7 @@ export class RuntimeMetadataResolver {
|
|||||||
} else if (provider instanceof Provider) {
|
} else if (provider instanceof Provider) {
|
||||||
return this.getProviderMetadata(provider);
|
return this.getProviderMetadata(provider);
|
||||||
} else {
|
} else {
|
||||||
return this.getTypeMetadata(provider, null);
|
return this.getTypeMetadata(provider, staticTypeModuleUrl(provider));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -270,12 +308,16 @@ export class RuntimeMetadataResolver {
|
|||||||
}
|
}
|
||||||
return new cpl.CompileProviderMetadata({
|
return new cpl.CompileProviderMetadata({
|
||||||
token: this.getTokenMetadata(provider.token),
|
token: this.getTokenMetadata(provider.token),
|
||||||
useClass: isPresent(provider.useClass) ? this.getTypeMetadata(provider.useClass, null) : null,
|
useClass:
|
||||||
|
isPresent(provider.useClass) ?
|
||||||
|
this.getTypeMetadata(provider.useClass, staticTypeModuleUrl(provider.useClass)) :
|
||||||
|
null,
|
||||||
useValue: isPresent(provider.useValue) ?
|
useValue: isPresent(provider.useValue) ?
|
||||||
new cpl.CompileIdentifierMetadata({runtime: provider.useValue}) :
|
new cpl.CompileIdentifierMetadata({runtime: provider.useValue}) :
|
||||||
null,
|
null,
|
||||||
useFactory: isPresent(provider.useFactory) ?
|
useFactory: isPresent(provider.useFactory) ?
|
||||||
this.getFactoryMetadata(provider.useFactory, null) :
|
this.getFactoryMetadata(provider.useFactory,
|
||||||
|
staticTypeModuleUrl(provider.useFactory)) :
|
||||||
null,
|
null,
|
||||||
useExisting: isPresent(provider.useExisting) ? this.getTokenMetadata(provider.useExisting) :
|
useExisting: isPresent(provider.useExisting) ? this.getTokenMetadata(provider.useExisting) :
|
||||||
null,
|
null,
|
||||||
@ -345,8 +387,16 @@ function flattenArray(tree: any[], out: Array<Type | any[]>): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidType(value: Type): boolean {
|
function isStaticType(value: any): boolean {
|
||||||
return isPresent(value) && (value instanceof Type);
|
return isStringMap(value) && isPresent(value['name']) && isPresent(value['moduleId']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidType(value: any): boolean {
|
||||||
|
return isStaticType(value) || (value instanceof Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
function staticTypeModuleUrl(value: any): string {
|
||||||
|
return isStaticType(value) ? value['moduleId'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcModuleUrl(reflector: ReflectorReader, type: Type,
|
function calcModuleUrl(reflector: ReflectorReader, type: Type,
|
@ -44,7 +44,7 @@ import {StyleCompiler, StylesCompileDependency, StylesCompileResult} from './sty
|
|||||||
import {ViewCompiler} from './view_compiler/view_compiler';
|
import {ViewCompiler} from './view_compiler/view_compiler';
|
||||||
import {TemplateParser} from './template_parser';
|
import {TemplateParser} from './template_parser';
|
||||||
import {DirectiveNormalizer} from './directive_normalizer';
|
import {DirectiveNormalizer} from './directive_normalizer';
|
||||||
import {RuntimeMetadataResolver} from './runtime_metadata';
|
import {CompileMetadataResolver} from './metadata_resolver';
|
||||||
import {ComponentFactory} from 'angular2/src/core/linker/component_factory';
|
import {ComponentFactory} from 'angular2/src/core/linker/component_factory';
|
||||||
import {
|
import {
|
||||||
ComponentResolver,
|
ComponentResolver,
|
||||||
@ -71,7 +71,7 @@ export class RuntimeCompiler implements ComponentResolver {
|
|||||||
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
|
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
|
||||||
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
|
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
|
||||||
|
|
||||||
constructor(private _runtimeMetadataResolver: RuntimeMetadataResolver,
|
constructor(private _metadataResolver: CompileMetadataResolver,
|
||||||
private _templateNormalizer: DirectiveNormalizer,
|
private _templateNormalizer: DirectiveNormalizer,
|
||||||
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
||||||
private _viewCompiler: ViewCompiler, private _xhr: XHR,
|
private _viewCompiler: ViewCompiler, private _xhr: XHR,
|
||||||
@ -79,7 +79,7 @@ export class RuntimeCompiler implements ComponentResolver {
|
|||||||
|
|
||||||
resolveComponent(componentType: Type): Promise<ComponentFactory> {
|
resolveComponent(componentType: Type): Promise<ComponentFactory> {
|
||||||
var compMeta: CompileDirectiveMetadata =
|
var compMeta: CompileDirectiveMetadata =
|
||||||
this._runtimeMetadataResolver.getDirectiveMetadata(componentType);
|
this._metadataResolver.getDirectiveMetadata(componentType);
|
||||||
var hostCacheKey = this._hostCacheKeys.get(componentType);
|
var hostCacheKey = this._hostCacheKeys.get(componentType);
|
||||||
if (isBlank(hostCacheKey)) {
|
if (isBlank(hostCacheKey)) {
|
||||||
hostCacheKey = new Object();
|
hostCacheKey = new Object();
|
||||||
@ -146,9 +146,9 @@ export class RuntimeCompiler implements ComponentResolver {
|
|||||||
|
|
||||||
var childCacheKey = dep.comp.type.runtime;
|
var childCacheKey = dep.comp.type.runtime;
|
||||||
var childViewDirectives: CompileDirectiveMetadata[] =
|
var childViewDirectives: CompileDirectiveMetadata[] =
|
||||||
this._runtimeMetadataResolver.getViewDirectivesMetadata(dep.comp.type.runtime);
|
this._metadataResolver.getViewDirectivesMetadata(dep.comp.type.runtime);
|
||||||
var childViewPipes: CompilePipeMetadata[] =
|
var childViewPipes: CompilePipeMetadata[] =
|
||||||
this._runtimeMetadataResolver.getViewPipesMetadata(dep.comp.type.runtime);
|
this._metadataResolver.getViewPipesMetadata(dep.comp.type.runtime);
|
||||||
var childIsRecursive = ListWrapper.contains(childCompilingComponentsPath, childCacheKey);
|
var childIsRecursive = ListWrapper.contains(childCompilingComponentsPath, childCacheKey);
|
||||||
childCompilingComponentsPath.push(childCacheKey);
|
childCompilingComponentsPath.push(childCacheKey);
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
isArray,
|
isArray,
|
||||||
isPresent,
|
isPresent,
|
||||||
|
isBlank,
|
||||||
isPrimitive,
|
isPrimitive,
|
||||||
|
isStringMap,
|
||||||
|
CONST_EXPR,
|
||||||
|
FunctionWrapper
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
import {
|
import {
|
||||||
AttributeMetadata,
|
AttributeMetadata,
|
||||||
@ -22,6 +26,16 @@ import {
|
|||||||
QueryMetadata,
|
QueryMetadata,
|
||||||
} from 'angular2/src/core/metadata';
|
} from 'angular2/src/core/metadata';
|
||||||
import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader';
|
import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader';
|
||||||
|
import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||||
|
import {Provider} from 'angular2/src/core/di/provider';
|
||||||
|
import {
|
||||||
|
HostMetadata,
|
||||||
|
OptionalMetadata,
|
||||||
|
InjectableMetadata,
|
||||||
|
SelfMetadata,
|
||||||
|
SkipSelfMetadata,
|
||||||
|
InjectMetadata
|
||||||
|
} from "angular2/src/core/di/metadata";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
||||||
@ -36,7 +50,7 @@ export interface StaticReflectorHost {
|
|||||||
* @param moduleId is a string identifier for a module as an absolute path.
|
* @param moduleId is a string identifier for a module as an absolute path.
|
||||||
* @returns the metadata for the given module.
|
* @returns the metadata for the given module.
|
||||||
*/
|
*/
|
||||||
getMetadataFor(moduleId: string): {[key: string]: any};
|
getMetadataFor(modulePath: string): {[key: string]: any};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a module from an import statement form to an absolute path.
|
* Resolve a module from an import statement form to an absolute path.
|
||||||
@ -44,6 +58,9 @@ export interface StaticReflectorHost {
|
|||||||
* @param containingFile for relative imports, the path of the file containing the import
|
* @param containingFile for relative imports, the path of the file containing the import
|
||||||
*/
|
*/
|
||||||
resolveModule(moduleName: string, containingFile?: string): string;
|
resolveModule(moduleName: string, containingFile?: string): string;
|
||||||
|
|
||||||
|
findDeclaration(modulePath: string,
|
||||||
|
symbolName: string): {declarationPath: string, declaredName: string};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,6 +82,8 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
private propertyCache = new Map<StaticType, {[key: string]: any}>();
|
private propertyCache = new Map<StaticType, {[key: string]: any}>();
|
||||||
private parameterCache = new Map<StaticType, any[]>();
|
private parameterCache = new Map<StaticType, any[]>();
|
||||||
private metadataCache = new Map<string, {[key: string]: any}>();
|
private metadataCache = new Map<string, {[key: string]: any}>();
|
||||||
|
private conversionMap = new Map<StaticType, (moduleContext: string, args: any[]) => any>();
|
||||||
|
|
||||||
constructor(private host: StaticReflectorHost) { this.initializeConversionMap(); }
|
constructor(private host: StaticReflectorHost) { this.initializeConversionMap(); }
|
||||||
|
|
||||||
importUri(typeOrFunc: any): string { return (<StaticType>typeOrFunc).moduleId; }
|
importUri(typeOrFunc: any): string { return (<StaticType>typeOrFunc).moduleId; }
|
||||||
@ -91,13 +110,11 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
if (!isPresent(annotations)) {
|
if (!isPresent(annotations)) {
|
||||||
let classMetadata = this.getTypeMetadata(type);
|
let classMetadata = this.getTypeMetadata(type);
|
||||||
if (isPresent(classMetadata['decorators'])) {
|
if (isPresent(classMetadata['decorators'])) {
|
||||||
annotations = (<any[]>classMetadata['decorators'])
|
annotations = this.simplify(type.moduleId, classMetadata['decorators'], false);
|
||||||
.map(decorator => this.convertKnownDecorator(type.moduleId, decorator))
|
|
||||||
.filter(decorator => isPresent(decorator));
|
|
||||||
} else {
|
} else {
|
||||||
annotations = [];
|
annotations = [];
|
||||||
}
|
}
|
||||||
this.annotationCache.set(type, annotations);
|
this.annotationCache.set(type, annotations.filter(ann => isPresent(ann)));
|
||||||
}
|
}
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
@ -106,10 +123,15 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
let propMetadata = this.propertyCache.get(type);
|
let propMetadata = this.propertyCache.get(type);
|
||||||
if (!isPresent(propMetadata)) {
|
if (!isPresent(propMetadata)) {
|
||||||
let classMetadata = this.getTypeMetadata(type);
|
let classMetadata = this.getTypeMetadata(type);
|
||||||
propMetadata = this.getPropertyMetadata(type.moduleId, classMetadata['members']);
|
let members = isPresent(classMetadata) ? classMetadata['members'] : {};
|
||||||
if (!isPresent(propMetadata)) {
|
propMetadata = mapStringMap(members, (propData, propName) => {
|
||||||
propMetadata = {};
|
let prop = (<any[]>propData).find(a => a['__symbolic'] == 'property');
|
||||||
}
|
if (isPresent(prop) && isPresent(prop['decorators'])) {
|
||||||
|
return this.simplify(type.moduleId, prop['decorators'], false);
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
this.propertyCache.set(type, propMetadata);
|
this.propertyCache.set(type, propMetadata);
|
||||||
}
|
}
|
||||||
return propMetadata;
|
return propMetadata;
|
||||||
@ -119,15 +141,26 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
let parameters = this.parameterCache.get(type);
|
let parameters = this.parameterCache.get(type);
|
||||||
if (!isPresent(parameters)) {
|
if (!isPresent(parameters)) {
|
||||||
let classMetadata = this.getTypeMetadata(type);
|
let classMetadata = this.getTypeMetadata(type);
|
||||||
if (isPresent(classMetadata)) {
|
let members = isPresent(classMetadata) ? classMetadata['members'] : null;
|
||||||
let members = classMetadata['members'];
|
let ctorData = isPresent(members) ? members['__ctor__'] : null;
|
||||||
if (isPresent(members)) {
|
if (isPresent(ctorData)) {
|
||||||
let ctorData = members['__ctor__'];
|
let ctor = (<any[]>ctorData).find(a => a['__symbolic'] == 'constructor');
|
||||||
if (isPresent(ctorData)) {
|
let parameterTypes = <any[]>this.simplify(type.moduleId, ctor['parameters'], false);
|
||||||
let ctor = (<any[]>ctorData).find(a => a['__symbolic'] === 'constructor');
|
let parameterDecorators =
|
||||||
parameters = this.simplify(type.moduleId, ctor['parameters']);
|
<any[]>this.simplify(type.moduleId, ctor['parameterDecorators'], false);
|
||||||
|
|
||||||
|
parameters = [];
|
||||||
|
ListWrapper.forEachWithIndex(parameterTypes, (paramType, index) => {
|
||||||
|
let nestedResult = [];
|
||||||
|
if (isPresent(paramType)) {
|
||||||
|
nestedResult.push(paramType);
|
||||||
}
|
}
|
||||||
}
|
let decorators = isPresent(parameterDecorators) ? parameterDecorators[index] : null;
|
||||||
|
if (isPresent(decorators)) {
|
||||||
|
ListWrapper.addAll(nestedResult, decorators);
|
||||||
|
}
|
||||||
|
parameters.push(nestedResult);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (!isPresent(parameters)) {
|
if (!isPresent(parameters)) {
|
||||||
parameters = [];
|
parameters = [];
|
||||||
@ -137,201 +170,82 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private conversionMap = new Map<StaticType, (moduleContext: string, expression: any) => any>();
|
private registerDecoratorOrConstructor(type: StaticType, ctor: any,
|
||||||
private initializeConversionMap(): any {
|
crossModuleProps: any[] = CONST_EXPR([])): void {
|
||||||
let core_metadata = this.host.resolveModule('angular2/src/core/metadata');
|
this.conversionMap.set(type, (moduleContext: string, args: any[]) => {
|
||||||
let conversionMap = this.conversionMap;
|
let argValues = [];
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Directive'),
|
ListWrapper.forEachWithIndex(args, (arg, index) => {
|
||||||
(moduleContext, expression) => {
|
let argValue;
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
if (isStringMap(arg) && isBlank(arg['__symbolic'])) {
|
||||||
if (!isPresent(p0)) {
|
argValue =
|
||||||
p0 = {};
|
mapStringMap(arg, (value, key) => this.simplify(
|
||||||
}
|
moduleContext, value, crossModuleProps.indexOf(key) !== -1));
|
||||||
return new DirectiveMetadata({
|
} else {
|
||||||
selector: p0['selector'],
|
argValue = this.simplify(moduleContext, arg, crossModuleProps.indexOf(index) !== -1);
|
||||||
inputs: p0['inputs'],
|
|
||||||
outputs: p0['outputs'],
|
|
||||||
events: p0['events'],
|
|
||||||
host: p0['host'],
|
|
||||||
bindings: p0['bindings'],
|
|
||||||
providers: p0['providers'],
|
|
||||||
exportAs: p0['exportAs'],
|
|
||||||
queries: p0['queries'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Component'),
|
|
||||||
(moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
|
||||||
if (!isPresent(p0)) {
|
|
||||||
p0 = {};
|
|
||||||
}
|
|
||||||
return new ComponentMetadata({
|
|
||||||
selector: p0['selector'],
|
|
||||||
inputs: p0['inputs'],
|
|
||||||
outputs: p0['outputs'],
|
|
||||||
properties: p0['properties'],
|
|
||||||
events: p0['events'],
|
|
||||||
host: p0['host'],
|
|
||||||
exportAs: p0['exportAs'],
|
|
||||||
moduleId: p0['moduleId'],
|
|
||||||
bindings: p0['bindings'],
|
|
||||||
providers: p0['providers'],
|
|
||||||
viewBindings: p0['viewBindings'],
|
|
||||||
viewProviders: p0['viewProviders'],
|
|
||||||
changeDetection: p0['changeDetection'],
|
|
||||||
queries: p0['queries'],
|
|
||||||
templateUrl: p0['templateUrl'],
|
|
||||||
template: p0['template'],
|
|
||||||
styleUrls: p0['styleUrls'],
|
|
||||||
styles: p0['styles'],
|
|
||||||
directives: p0['directives'],
|
|
||||||
pipes: p0['pipes'],
|
|
||||||
encapsulation: p0['encapsulation']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Input'),
|
|
||||||
(moduleContext, expression) => new InputMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Output'),
|
|
||||||
(moduleContext, expression) => new OutputMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
|
||||||
if (!isPresent(p0)) {
|
|
||||||
p0 = {};
|
|
||||||
}
|
|
||||||
return new ViewMetadata({
|
|
||||||
templateUrl: p0['templateUrl'],
|
|
||||||
template: p0['template'],
|
|
||||||
directives: p0['directives'],
|
|
||||||
pipes: p0['pipes'],
|
|
||||||
encapsulation: p0['encapsulation'],
|
|
||||||
styles: p0['styles'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Attribute'),
|
|
||||||
(moduleContext, expression) => new AttributeMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
|
||||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
|
||||||
if (!isPresent(p1)) {
|
|
||||||
p1 = {};
|
|
||||||
}
|
|
||||||
return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'ContentChildren'),
|
|
||||||
(moduleContext, expression) => new ContentChildrenMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'ContentChild'),
|
|
||||||
(moduleContext, expression) => new ContentChildMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewChildren'),
|
|
||||||
(moduleContext, expression) => new ViewChildrenMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewChild'),
|
|
||||||
(moduleContext, expression) => new ViewChildMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewQuery'),
|
|
||||||
(moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
|
||||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
|
||||||
if (!isPresent(p1)) {
|
|
||||||
p1 = {};
|
|
||||||
}
|
|
||||||
return new ViewQueryMetadata(p0, {
|
|
||||||
descendants: p1['descendants'],
|
|
||||||
first: p1['first'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Pipe'), (moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
|
||||||
if (!isPresent(p0)) {
|
|
||||||
p0 = {};
|
|
||||||
}
|
|
||||||
return new PipeMetadata({
|
|
||||||
name: p0['name'],
|
|
||||||
pure: p0['pure'],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'HostBinding'),
|
|
||||||
(moduleContext, expression) => new HostBindingMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'HostListener'),
|
|
||||||
(moduleContext, expression) => new HostListenerMetadata(
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0),
|
|
||||||
this.getDecoratorParameter(moduleContext, expression, 1)));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private convertKnownDecorator(moduleContext: string, expression: {[key: string]: any}): any {
|
|
||||||
let converter = this.conversionMap.get(this.getDecoratorType(moduleContext, expression));
|
|
||||||
if (isPresent(converter)) return converter(moduleContext, expression);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getDecoratorType(moduleContext: string, expression: {[key: string]: any}): StaticType {
|
|
||||||
if (isMetadataSymbolicCallExpression(expression)) {
|
|
||||||
let target = expression['expression'];
|
|
||||||
if (isMetadataSymbolicReferenceExpression(target)) {
|
|
||||||
let moduleId = this.host.resolveModule(target['module'], moduleContext);
|
|
||||||
return this.getStaticType(moduleId, target['name']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getDecoratorParameter(moduleContext: string, expression: {[key: string]: any},
|
|
||||||
index: number): any {
|
|
||||||
if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) &&
|
|
||||||
(<any[]>expression['arguments']).length <= index + 1) {
|
|
||||||
return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getPropertyMetadata(moduleContext: string,
|
|
||||||
value: {[key: string]: any}): {[key: string]: any} {
|
|
||||||
if (isPresent(value)) {
|
|
||||||
let result = {};
|
|
||||||
StringMapWrapper.forEach(value, (value, name) => {
|
|
||||||
let data = this.getMemberData(moduleContext, value);
|
|
||||||
if (isPresent(data)) {
|
|
||||||
let propertyData = data.filter(d => d['kind'] == "property")
|
|
||||||
.map(d => d['directives'])
|
|
||||||
.reduce((p, c) => (<any[]>p).concat(<any[]>c), []);
|
|
||||||
if (propertyData.length != 0) {
|
|
||||||
StringMapWrapper.set(result, name, propertyData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
argValues.push(argValue);
|
||||||
});
|
});
|
||||||
return result;
|
return FunctionWrapper.apply(reflector.factory(ctor), argValues);
|
||||||
}
|
});
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
private initializeConversionMap(): void {
|
||||||
private getMemberData(moduleContext: string, member: { [key: string]: any }[]): { [key: string]: any }[] {
|
let coreDecorators = this.host.resolveModule('angular2/src/core/metadata');
|
||||||
// clang-format on
|
let diDecorators = this.host.resolveModule('angular2/src/core/di/decorators');
|
||||||
let result = [];
|
let diMetadata = this.host.resolveModule('angular2/src/core/di/metadata');
|
||||||
if (isPresent(member)) {
|
|
||||||
for (let item of member) {
|
let provider = this.host.resolveModule('angular2/src/core/di/provider');
|
||||||
result.push({
|
this.registerDecoratorOrConstructor(this.getStaticType(provider, 'Provider'), Provider);
|
||||||
kind: item['__symbolic'],
|
|
||||||
directives:
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Host'), HostMetadata);
|
||||||
isPresent(item['decorators']) ?
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Injectable'),
|
||||||
(<any[]>item['decorators'])
|
InjectableMetadata);
|
||||||
.map(decorator => this.convertKnownDecorator(moduleContext, decorator))
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Self'), SelfMetadata);
|
||||||
.filter(d => isPresent(d)) :
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'SkipSelf'),
|
||||||
null
|
SkipSelfMetadata);
|
||||||
});
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Inject'), InjectMetadata);
|
||||||
}
|
this.registerDecoratorOrConstructor(this.getStaticType(diDecorators, 'Optional'),
|
||||||
}
|
OptionalMetadata);
|
||||||
return result;
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Attribute'),
|
||||||
|
AttributeMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Query'), QueryMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewQuery'),
|
||||||
|
ViewQueryMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ContentChild'),
|
||||||
|
ContentChildMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ContentChildren'),
|
||||||
|
ContentChildrenMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewChild'),
|
||||||
|
ViewChildMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'ViewChildren'),
|
||||||
|
ViewChildrenMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Input'), InputMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Output'),
|
||||||
|
OutputMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Pipe'), PipeMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'HostBinding'),
|
||||||
|
HostBindingMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'HostListener'),
|
||||||
|
HostListenerMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Directive'),
|
||||||
|
DirectiveMetadata, ['bindings', 'providers']);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(coreDecorators, 'Component'),
|
||||||
|
ComponentMetadata,
|
||||||
|
['bindings', 'providers', 'directives', 'pipes']);
|
||||||
|
|
||||||
|
// Note: Some metadata classes can be used directly with Provider.deps.
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'HostMetadata'),
|
||||||
|
HostMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'SelfMetadata'),
|
||||||
|
SelfMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'SkipSelfMetadata'),
|
||||||
|
SkipSelfMetadata);
|
||||||
|
this.registerDecoratorOrConstructor(this.getStaticType(diMetadata, 'OptionalMetadata'),
|
||||||
|
OptionalMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public simplify(moduleContext: string, value: any): any {
|
public simplify(moduleContext: string, value: any, crossModules: boolean): any {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
|
|
||||||
function simplify(expression: any): any {
|
function simplify(expression: any): any {
|
||||||
@ -418,23 +332,44 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
|
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
|
||||||
return null;
|
return null;
|
||||||
case "reference":
|
case "reference":
|
||||||
let referenceModuleName =
|
let referenceModuleName;
|
||||||
_this.host.resolveModule(expression['module'], moduleContext);
|
let declarationPath = moduleContext;
|
||||||
let referenceModule = _this.getModuleMetadata(referenceModuleName);
|
let declaredName = expression['name'];
|
||||||
let referenceValue = referenceModule['metadata'][expression['name']];
|
if (isPresent(expression['module'])) {
|
||||||
if (isClassMetadata(referenceValue)) {
|
referenceModuleName = _this.host.resolveModule(expression['module'], moduleContext);
|
||||||
// Convert to a pseudo type
|
let decl = _this.host.findDeclaration(referenceModuleName, expression['name']);
|
||||||
return _this.getStaticType(referenceModuleName, expression['name']);
|
declarationPath = decl['declarationPath'];
|
||||||
|
declaredName = decl['declaredName'];
|
||||||
}
|
}
|
||||||
return _this.simplify(referenceModuleName, referenceValue);
|
let result;
|
||||||
|
if (crossModules || isBlank(expression['module'])) {
|
||||||
|
let moduleMetadata = _this.getModuleMetadata(declarationPath);
|
||||||
|
let declarationValue = moduleMetadata['metadata'][declaredName];
|
||||||
|
if (isClassMetadata(declarationValue)) {
|
||||||
|
result = _this.getStaticType(declarationPath, declaredName);
|
||||||
|
} else {
|
||||||
|
result = _this.simplify(declarationPath, declarationValue, crossModules);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = _this.getStaticType(declarationPath, declaredName);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
case "new":
|
||||||
case "call":
|
case "call":
|
||||||
return null;
|
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);
|
||||||
|
let args = expression['arguments'];
|
||||||
|
if (isBlank(args)) {
|
||||||
|
args = [];
|
||||||
|
}
|
||||||
|
return isPresent(converter) ? converter(moduleContext, args) : null;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let result = {};
|
return mapStringMap(expression, (value, name) => simplify(value));
|
||||||
StringMapWrapper.forEach(expression, (value, name) => { result[name] = simplify(value); });
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -467,15 +402,14 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMetadataSymbolicCallExpression(expression: any): boolean {
|
|
||||||
return !isPrimitive(expression) && !isArray(expression) && expression['__symbolic'] == 'call';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isMetadataSymbolicReferenceExpression(expression: any): boolean {
|
|
||||||
return !isPrimitive(expression) && !isArray(expression) &&
|
|
||||||
expression['__symbolic'] == 'reference';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isClassMetadata(expression: any): boolean {
|
function isClassMetadata(expression: any): boolean {
|
||||||
return !isPrimitive(expression) && !isArray(expression) && expression['__symbolic'] == 'class';
|
return !isPrimitive(expression) && !isArray(expression) && expression['__symbolic'] == 'class';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapStringMap(input: {[key: string]: any},
|
||||||
|
transform: (value: any, key: string) => any): {[key: string]: any} {
|
||||||
|
if (isBlank(input)) return {};
|
||||||
|
var result = {};
|
||||||
|
StringMapWrapper.keys(input).forEach((key) => { result[key] = transform(input[key], key); });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
library angular2.test.compiler.runtime_metadata_fixture;
|
library angular2.test.compiler.metadata_resolver_fixture;
|
||||||
|
|
||||||
import "package:angular2/core.dart" show Component;
|
import "package:angular2/core.dart" show Component;
|
||||||
|
|
@ -14,7 +14,7 @@ import {
|
|||||||
} from 'angular2/testing_internal';
|
} from 'angular2/testing_internal';
|
||||||
|
|
||||||
import {IS_DART, stringify} from 'angular2/src/facade/lang';
|
import {IS_DART, stringify} from 'angular2/src/facade/lang';
|
||||||
import {RuntimeMetadataResolver} from 'angular2/src/compiler/runtime_metadata';
|
import {CompileMetadataResolver} from 'angular2/src/compiler/metadata_resolver';
|
||||||
import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/metadata/lifecycle_hooks';
|
import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/metadata/lifecycle_hooks';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
@ -36,15 +36,15 @@ import {
|
|||||||
import {TEST_PROVIDERS} from './test_bindings';
|
import {TEST_PROVIDERS} from './test_bindings';
|
||||||
import {MODULE_SUFFIX} from 'angular2/src/compiler/util';
|
import {MODULE_SUFFIX} from 'angular2/src/compiler/util';
|
||||||
import {PLATFORM_DIRECTIVES} from 'angular2/src/core/platform_directives_and_pipes';
|
import {PLATFORM_DIRECTIVES} from 'angular2/src/core/platform_directives_and_pipes';
|
||||||
import {MalformedStylesComponent} from './runtime_metadata_fixture';
|
import {MalformedStylesComponent} from './metadata_resolver_fixture';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('RuntimeMetadataResolver', () => {
|
describe('CompileMetadataResolver', () => {
|
||||||
beforeEachProviders(() => TEST_PROVIDERS);
|
beforeEachProviders(() => TEST_PROVIDERS);
|
||||||
|
|
||||||
describe('getMetadata', () => {
|
describe('getMetadata', () => {
|
||||||
it('should read metadata',
|
it('should read metadata',
|
||||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
var meta = resolver.getDirectiveMetadata(ComponentWithEverything);
|
var meta = resolver.getDirectiveMetadata(ComponentWithEverything);
|
||||||
expect(meta.selector).toEqual('someSelector');
|
expect(meta.selector).toEqual('someSelector');
|
||||||
expect(meta.exportAs).toEqual('someExportAs');
|
expect(meta.exportAs).toEqual('someExportAs');
|
||||||
@ -67,16 +67,16 @@ export function main() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use the moduleUrl from the reflector if none is given',
|
it('should use the moduleUrl from the reflector if none is given',
|
||||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
var value: string =
|
var value: string =
|
||||||
resolver.getDirectiveMetadata(ComponentWithoutModuleId).type.moduleUrl;
|
resolver.getDirectiveMetadata(ComponentWithoutModuleId).type.moduleUrl;
|
||||||
var expectedEndValue =
|
var expectedEndValue =
|
||||||
IS_DART ? 'test/compiler/runtime_metadata_spec.dart' : './ComponentWithoutModuleId';
|
IS_DART ? 'test/compiler/metadata_resolver_spec.dart' : './ComponentWithoutModuleId';
|
||||||
expect(value.endsWith(expectedEndValue)).toBe(true);
|
expect(value.endsWith(expectedEndValue)).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should throw when metadata is incorrectly typed',
|
it('should throw when metadata is incorrectly typed',
|
||||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
if (!IS_DART) {
|
if (!IS_DART) {
|
||||||
expect(() => resolver.getDirectiveMetadata(MalformedStylesComponent))
|
expect(() => resolver.getDirectiveMetadata(MalformedStylesComponent))
|
||||||
.toThrowError(`Expected 'styles' to be an array of strings.`);
|
.toThrowError(`Expected 'styles' to be an array of strings.`);
|
||||||
@ -87,7 +87,7 @@ export function main() {
|
|||||||
describe('getViewDirectivesMetadata', () => {
|
describe('getViewDirectivesMetadata', () => {
|
||||||
|
|
||||||
it('should return the directive metadatas',
|
it('should return the directive metadatas',
|
||||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||||
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
||||||
}));
|
}));
|
||||||
@ -97,7 +97,7 @@ export function main() {
|
|||||||
() => [provide(PLATFORM_DIRECTIVES, {useValue: [ADirective], multi: true})]);
|
() => [provide(PLATFORM_DIRECTIVES, {useValue: [ADirective], multi: true})]);
|
||||||
|
|
||||||
it('should include platform directives when available',
|
it('should include platform directives when available',
|
||||||
inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
||||||
.toContain(resolver.getDirectiveMetadata(ADirective));
|
.toContain(resolver.getDirectiveMetadata(ADirective));
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
@ -1,18 +1,32 @@
|
|||||||
import {
|
import {describe, it, iit, expect, ddescribe, beforeEach} from 'angular2/testing_internal';
|
||||||
describe,
|
import {IS_DART} from 'angular2/src/facade/lang';
|
||||||
it,
|
|
||||||
expect,
|
|
||||||
} from 'angular2/testing_internal';
|
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {StaticReflector, StaticReflectorHost} from 'angular2/src/compiler/static_reflector';
|
import {StaticReflector, StaticReflectorHost} from 'angular2/src/compiler/static_reflector';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('StaticReflector', () => {
|
// Static reflector is not supported in Dart
|
||||||
it('should get annotations for NgFor', () => {
|
// as we use reflection to create objects.
|
||||||
let host = new MockReflectorHost();
|
if (IS_DART) return;
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
|
describe('StaticReflector', () => {
|
||||||
|
let host: StaticReflectorHost;
|
||||||
|
let reflector: StaticReflector;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
host = new MockReflectorHost();
|
||||||
|
reflector = new StaticReflector(host);
|
||||||
|
});
|
||||||
|
|
||||||
|
function singleModuleSimplify(moduleContext: string, value: any) {
|
||||||
|
return reflector.simplify(moduleContext, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function crossModuleSimplify(moduleContext: string, value: any) {
|
||||||
|
return reflector.simplify(moduleContext, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should get annotations for NgFor', () => {
|
||||||
let NgFor = reflector.getStaticType(
|
let NgFor = reflector.getStaticType(
|
||||||
host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor');
|
host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor');
|
||||||
let annotations = reflector.annotations(NgFor);
|
let annotations = reflector.annotations(NgFor);
|
||||||
@ -20,12 +34,10 @@ export function main() {
|
|||||||
let annotation = annotations[0];
|
let annotation = annotations[0];
|
||||||
expect(annotation.selector).toEqual('[ngFor][ngForOf]');
|
expect(annotation.selector).toEqual('[ngFor][ngForOf]');
|
||||||
expect(annotation.inputs).toEqual(['ngForTrackBy', 'ngForOf', 'ngForTemplate']);
|
expect(annotation.inputs).toEqual(['ngForTrackBy', 'ngForOf', 'ngForTemplate']);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get constructor for NgFor', () => {
|
it('should get constructor for NgFor', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let NgFor = reflector.getStaticType(
|
let NgFor = reflector.getStaticType(
|
||||||
host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor');
|
host.resolveModule('angular2/src/common/directives/ng_for'), 'NgFor');
|
||||||
let ViewContainerRef = reflector.getStaticType(
|
let ViewContainerRef = reflector.getStaticType(
|
||||||
@ -41,34 +53,32 @@ export function main() {
|
|||||||
|
|
||||||
let parameters = reflector.parameters(NgFor);
|
let parameters = reflector.parameters(NgFor);
|
||||||
expect(parameters)
|
expect(parameters)
|
||||||
.toEqual([ViewContainerRef, TemplateRef, IterableDiffers, ChangeDetectorRef]);
|
.toEqual([[ViewContainerRef], [TemplateRef], [IterableDiffers], [ChangeDetectorRef]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get annotations for HeroDetailComponent', () => {
|
it('should get annotations for HeroDetailComponent', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let HeroDetailComponent =
|
let HeroDetailComponent =
|
||||||
reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent');
|
reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent');
|
||||||
let annotations = reflector.annotations(HeroDetailComponent);
|
let annotations = reflector.annotations(HeroDetailComponent);
|
||||||
expect(annotations.length).toEqual(1);
|
expect(annotations.length).toEqual(1);
|
||||||
let annotation = annotations[0];
|
let annotation = annotations[0];
|
||||||
expect(annotation.selector).toEqual('my-hero-detail');
|
expect(annotation.selector).toEqual('my-hero-detail');
|
||||||
|
expect(annotation.directives)
|
||||||
|
.toEqual([
|
||||||
|
[
|
||||||
|
reflector.getStaticType(host.resolveModule('angular2/src/common/directives/ng_for'),
|
||||||
|
'NgFor')
|
||||||
|
]
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get and empty annotation list for an unknown class', () => {
|
it('should get and empty annotation list for an unknown class', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
||||||
let annotations = reflector.annotations(UnknownClass);
|
let annotations = reflector.annotations(UnknownClass);
|
||||||
expect(annotations).toEqual([]);
|
expect(annotations).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get propMetadata for HeroDetailComponent', () => {
|
it('should get propMetadata for HeroDetailComponent', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let HeroDetailComponent =
|
let HeroDetailComponent =
|
||||||
reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent');
|
reflector.getStaticType('/src/app/hero-detail.component.ts', 'HeroDetailComponent');
|
||||||
let props = reflector.propMetadata(HeroDetailComponent);
|
let props = reflector.propMetadata(HeroDetailComponent);
|
||||||
@ -76,254 +86,175 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should get an empty object from propMetadata for an unknown class', () => {
|
it('should get an empty object from propMetadata for an unknown class', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
||||||
let properties = reflector.propMetadata(UnknownClass);
|
let properties = reflector.propMetadata(UnknownClass);
|
||||||
expect(properties).toEqual({});
|
expect(properties).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get empty parameters list for an unknown class ', () => {
|
it('should get empty parameters list for an unknown class ', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
let UnknownClass = reflector.getStaticType('/src/app/app.component.ts', 'UnknownClass');
|
||||||
let parameters = reflector.parameters(UnknownClass);
|
let parameters = reflector.parameters(UnknownClass);
|
||||||
expect(parameters).toEqual([]);
|
expect(parameters).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify primitive into itself', () => {
|
it('should simplify primitive into itself', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', 1)).toBe(1);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', true)).toBe(true);
|
||||||
|
expect(singleModuleSimplify('', "some value")).toBe("some value");
|
||||||
expect(reflector.simplify('', 1)).toBe(1);
|
|
||||||
expect(reflector.simplify('', true)).toBe(true);
|
|
||||||
expect(reflector.simplify('', "some value")).toBe("some value");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify an array into a copy of the array', () => {
|
it('should simplify an array into a copy of the array',
|
||||||
let host = new MockReflectorHost();
|
() => { expect(singleModuleSimplify('', [1, 2, 3])).toEqual([1, 2, 3]); });
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', [1, 2, 3])).toEqual([1, 2, 3]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should simplify an object to a copy of the object', () => {
|
it('should simplify an object to a copy of the object', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
let expr = {a: 1, b: 2, c: 3};
|
let expr = {a: 1, b: 2, c: 3};
|
||||||
expect(reflector.simplify('', expr)).toEqual(expr);
|
expect(singleModuleSimplify('', expr)).toEqual(expr);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify &&', () => {
|
it('should simplify &&', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: true}))).toBe(true);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: false}))).toBe(false);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: true}))).toBe(true);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: true}))).toBe(false);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: true, right: false}))).toBe(false);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: false}))).toBe(false);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: true}))).toBe(false);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&&', left: false, right: false}))).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify ||', () => {
|
it('should simplify ||', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: true}))).toBe(true);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: false}))).toBe(true);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: true}))).toBe(true);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: true}))).toBe(true);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: true, right: false}))).toBe(true);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: false}))).toBe(false);
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: true}))).toBe(true);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '||', left: false, right: false}))).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify &', () => {
|
it('should simplify &', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F}))).toBe(0x22 & 0x0F);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0}))).toBe(0x22 & 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0x0F}))).toBe(0x22 & 0x0F);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '&', left: 0x22, right: 0xF0}))).toBe(0x22 & 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify |', () => {
|
it('should simplify |', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify ^', () => {
|
it('should simplify ^', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0x0F}))).toBe(0x22 | 0x0F);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '|', left: 0x22, right: 0xF0}))).toBe(0x22 | 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify ==', () => {
|
it('should simplify ==', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0x22}))).toBe(0x22 == 0x22);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0}))).toBe(0x22 == 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0x22}))).toBe(0x22 == 0x22);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '==', left: 0x22, right: 0xF0}))).toBe(0x22 == 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify !=', () => {
|
it('should simplify !=', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22}))).toBe(0x22 != 0x22);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0}))).toBe(0x22 != 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0x22}))).toBe(0x22 != 0x22);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!=', left: 0x22, right: 0xF0}))).toBe(0x22 != 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify ===', () => {
|
it('should simplify ===', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0x22}))).toBe(0x22 === 0x22);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0}))).toBe(0x22 === 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0x22}))).toBe(0x22 === 0x22);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '===', left: 0x22, right: 0xF0}))).toBe(0x22 === 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify !==', () => {
|
it('should simplify !==', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22}))).toBe(0x22 !== 0x22);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0}))).toBe(0x22 !== 0xF0);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0x22}))).toBe(0x22 !== 0x22);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '!==', left: 0x22, right: 0xF0}))).toBe(0x22 !== 0xF0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify >', () => {
|
it('should simplify >', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 1}))).toBe(1 > 1);
|
||||||
let reflector = new StaticReflector(host);
|
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(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 1}))).toBe(1 > 1);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 1, right: 0}))).toBe(1 > 0);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>', left: 0, right: 1}))).toBe(0 > 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify >=', () => {
|
it('should simplify >=', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 1}))).toBe(1 >= 1);
|
||||||
let reflector = new StaticReflector(host);
|
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(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 1}))).toBe(1 >= 1);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 1, right: 0}))).toBe(1 >= 0);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>=', left: 0, right: 1}))).toBe(0 >= 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify <=', () => {
|
it('should simplify <=', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 1}))).toBe(1 <= 1);
|
||||||
let reflector = new StaticReflector(host);
|
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(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 1}))).toBe(1 <= 1);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 1, right: 0}))).toBe(1 <= 0);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<=', left: 0, right: 1}))).toBe(0 <= 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify <', () => {
|
it('should simplify <', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 1}))).toBe(1 < 1);
|
||||||
let reflector = new StaticReflector(host);
|
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(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 1}))).toBe(1 < 1);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 1, right: 0}))).toBe(1 < 0);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<', left: 0, right: 1}))).toBe(0 < 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify <<', () => {
|
it('should simplify <<', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '<<', left: 0x55, right: 2}))).toBe(0x55 << 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '<<', left: 0x55, right: 2}))).toBe(0x55 << 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify >>', () => {
|
it('should simplify >>', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '>>', left: 0x55, right: 2}))).toBe(0x55 >> 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '>>', left: 0x55, right: 2}))).toBe(0x55 >> 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify +', () => {
|
it('should simplify +', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '+', left: 0x55, right: 2}))).toBe(0x55 + 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '+', left: 0x55, right: 2}))).toBe(0x55 + 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify -', () => {
|
it('should simplify -', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '-', left: 0x55, right: 2}))).toBe(0x55 - 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '-', left: 0x55, right: 2}))).toBe(0x55 - 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify *', () => {
|
it('should simplify *', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '*', left: 0x55, right: 2}))).toBe(0x55 * 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '*', left: 0x55, right: 2}))).toBe(0x55 * 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify /', () => {
|
it('should simplify /', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '/', left: 0x55, right: 2}))).toBe(0x55 / 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '/', left: 0x55, right: 2}))).toBe(0x55 / 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify %', () => {
|
it('should simplify %', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'binop', operator: '%', left: 0x55, right: 2}))).toBe(0x55 % 2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'binop', operator: '%', left: 0x55, right: 2}))).toBe(0x55 % 2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify prefix -', () => {
|
it('should simplify prefix -', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '-', operand: 2}))).toBe(-2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify prefix ~', () => {
|
it('should simplify prefix ~', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2);
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '~', operand: 2}))).toBe(~2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify prefix !', () => {
|
it('should simplify prefix !', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '!', operand: true}))).toBe(!true);
|
||||||
let reflector = new StaticReflector(host);
|
expect(singleModuleSimplify('', ({ __symbolic: 'pre', operator: '!', operand: false}))).toBe(!false);
|
||||||
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '!', operand: true}))).toBe(!true);
|
|
||||||
expect(reflector.simplify('', ({ __symbolic: 'pre', operator: '!', operand: false}))).toBe(!false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify an array index', () => {
|
it('should simplify an array index', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(singleModuleSimplify('', ({__symbolic: "index", expression: [1, 2, 3], index: 2})))
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
|
|
||||||
expect(reflector.simplify('', ({__symbolic: "index", expression: [1, 2, 3], index: 2})))
|
|
||||||
.toBe(3);
|
.toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify an object index', () => {
|
it('should simplify an object index', () => {
|
||||||
let host = new MockReflectorHost();
|
|
||||||
let reflector = new StaticReflector(host);
|
|
||||||
let expr = {__symbolic: "select", expression: {a: 1, b: 2, c: 3}, member: "b"};
|
let expr = {__symbolic: "select", expression: {a: 1, b: 2, c: 3}, member: "b"};
|
||||||
expect(reflector.simplify('', expr)).toBe(2);
|
expect(singleModuleSimplify('', expr)).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should simplify a module reference', () => {
|
it('should simplify a module reference across modules', () => {
|
||||||
let host = new MockReflectorHost();
|
expect(crossModuleSimplify('/src/cases',
|
||||||
let reflector = new StaticReflector(host);
|
({__symbolic: "reference", module: "./extern", name: "s"})))
|
||||||
|
|
||||||
expect(reflector.simplify('/src/cases',
|
|
||||||
({__symbolic: "reference", module: "./extern", name: "s"})))
|
|
||||||
.toEqual("s");
|
.toEqual("s");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should simplify a module reference without crossing modules', () => {
|
||||||
|
expect(singleModuleSimplify('/src/cases',
|
||||||
|
({__symbolic: "reference", module: "./extern", name: "s"})))
|
||||||
|
.toEqual(reflector.getStaticType('/src/extern.d.ts', 's'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockReflectorHost implements StaticReflectorHost {
|
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};
|
||||||
|
}
|
||||||
resolveModule(moduleName: string, containingFile?: string): string {
|
resolveModule(moduleName: string, containingFile?: string): string {
|
||||||
function splitPath(path: string): string[] { return path.split(/\/|\\/g); }
|
function splitPath(path: string): string[] { return path.split(/\/|\\/g); }
|
||||||
|
|
||||||
@ -363,68 +294,80 @@ class MockReflectorHost implements StaticReflectorHost {
|
|||||||
|
|
||||||
getMetadataFor(moduleId: string): any {
|
getMetadataFor(moduleId: string): any {
|
||||||
return {
|
return {
|
||||||
'/tmp/angular2/src/common/directives/ng_for.d.ts':
|
'/tmp/angular2/src/common/forms/directives.d.ts':
|
||||||
{
|
{
|
||||||
"__symbolic": "module",
|
"__symbolic": "module",
|
||||||
"metadata":
|
"metadata": {
|
||||||
|
"FORM_DIRECTIVES": [
|
||||||
{
|
{
|
||||||
"NgFor":
|
"__symbolic": "reference",
|
||||||
{
|
"name": "NgFor",
|
||||||
"__symbolic": "class",
|
"module": "angular2/src/common/directives/ng_for"
|
||||||
"decorators":
|
}
|
||||||
[
|
]
|
||||||
{
|
}
|
||||||
"__symbolic": "call",
|
},
|
||||||
"expression": {
|
'/tmp/angular2/src/common/directives/ng_for.d.ts':
|
||||||
"__symbolic": "reference",
|
{
|
||||||
"name": "Directive",
|
"__symbolic": "module",
|
||||||
"module": "../../core/metadata"
|
"metadata":
|
||||||
},
|
{
|
||||||
"arguments":
|
"NgFor":
|
||||||
[
|
{
|
||||||
|
"__symbolic": "class",
|
||||||
|
"decorators":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"__symbolic": "call",
|
||||||
|
"expression": {
|
||||||
|
"__symbolic": "reference",
|
||||||
|
"name": "Directive",
|
||||||
|
"module": "../../core/metadata"
|
||||||
|
},
|
||||||
|
"arguments": [
|
||||||
{
|
{
|
||||||
"selector": "[ngFor][ngForOf]",
|
"selector": "[ngFor][ngForOf]",
|
||||||
"inputs": ["ngForTrackBy", "ngForOf", "ngForTemplate"]
|
"inputs": ["ngForTrackBy", "ngForOf", "ngForTemplate"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"members":
|
"members":
|
||||||
{
|
|
||||||
"__ctor__": [
|
|
||||||
{
|
{
|
||||||
"__symbolic": "constructor",
|
"__ctor__": [
|
||||||
"parameters":
|
{
|
||||||
[
|
"__symbolic": "constructor",
|
||||||
{
|
"parameters":
|
||||||
"__symbolic": "reference",
|
[
|
||||||
"module": "../../core/linker/view_container_ref",
|
{
|
||||||
"name": "ViewContainerRef"
|
"__symbolic": "reference",
|
||||||
},
|
"module": "../../core/linker/view_container_ref",
|
||||||
{
|
"name": "ViewContainerRef"
|
||||||
"__symbolic": "reference",
|
},
|
||||||
"module": "../../core/linker/template_ref",
|
{
|
||||||
"name": "TemplateRef"
|
"__symbolic": "reference",
|
||||||
},
|
"module": "../../core/linker/template_ref",
|
||||||
{
|
"name": "TemplateRef"
|
||||||
"__symbolic": "reference",
|
},
|
||||||
"module":
|
{
|
||||||
"../../core/change_detection/differs/iterable_differs",
|
"__symbolic": "reference",
|
||||||
"name": "IterableDiffers"
|
"module":
|
||||||
},
|
"../../core/change_detection/differs/iterable_differs",
|
||||||
{
|
"name": "IterableDiffers"
|
||||||
"__symbolic": "reference",
|
},
|
||||||
"module":
|
{
|
||||||
"../../core/change_detection/change_detector_ref",
|
"__symbolic": "reference",
|
||||||
"name": "ChangeDetectorRef"
|
"module":
|
||||||
}
|
"../../core/change_detection/change_detector_ref",
|
||||||
]
|
"name": "ChangeDetectorRef"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
},
|
|
||||||
'/tmp/angular2/src/core/linker/view_container_ref.d.ts':
|
'/tmp/angular2/src/core/linker/view_container_ref.d.ts':
|
||||||
{"metadata": {"ViewContainerRef": {"__symbolic": "class"}}},
|
{"metadata": {"ViewContainerRef": {"__symbolic": "class"}}},
|
||||||
'/tmp/angular2/src/core/linker/template_ref.d.ts':
|
'/tmp/angular2/src/core/linker/template_ref.d.ts':
|
||||||
@ -453,7 +396,15 @@ class MockReflectorHost implements StaticReflectorHost {
|
|||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"selector": "my-hero-detail",
|
"selector": "my-hero-detail",
|
||||||
"template": "\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n"
|
"template": "\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n",
|
||||||
|
"directives":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"__symbolic": "reference",
|
||||||
|
"name": "FORM_DIRECTIVES",
|
||||||
|
"module": "angular2/src/common/forms/directives"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user