feat(compiler): add TemplateCompiler
TemplateCompiler is the entry point to the new compiler Related to #3605 Closes #4220
This commit is contained in:
@ -93,8 +93,11 @@ export class DirectiveResolver {
|
||||
properties: mergedProperties,
|
||||
events: mergedEvents,
|
||||
host: mergedHost,
|
||||
dynamicLoadable: dm.dynamicLoadable,
|
||||
compiledHostTemplate: dm.compiledHostTemplate,
|
||||
bindings: dm.bindings,
|
||||
exportAs: dm.exportAs,
|
||||
moduleId: dm.moduleId,
|
||||
compileChildren: dm.compileChildren,
|
||||
changeDetection: dm.changeDetection,
|
||||
viewBindings: dm.viewBindings
|
||||
@ -108,6 +111,7 @@ export class DirectiveResolver {
|
||||
host: mergedHost,
|
||||
bindings: dm.bindings,
|
||||
exportAs: dm.exportAs,
|
||||
moduleId: dm.moduleId,
|
||||
compileChildren: dm.compileChildren
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Type, CONST_EXPR, isPresent} from 'angular2/src/core/facade/lang';
|
||||
import {Type, CONST_EXPR, isPresent, isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {
|
||||
RenderTemplateCmd,
|
||||
RenderCommandVisitor,
|
||||
@ -10,7 +10,35 @@ import {
|
||||
} from 'angular2/src/core/render/render';
|
||||
|
||||
export class CompiledTemplate {
|
||||
constructor(public id: string, public commands: TemplateCmd[]) {}
|
||||
private _changeDetectorFactories: Function[] = null;
|
||||
private _styles: string[] = null;
|
||||
private _commands: TemplateCmd[] = null;
|
||||
// Note: paramGetter is a function so that we can have cycles between templates!
|
||||
constructor(public id: number, private _paramGetter: Function) {}
|
||||
|
||||
private _init() {
|
||||
if (isBlank(this._commands)) {
|
||||
var params = this._paramGetter();
|
||||
this._changeDetectorFactories = params[0];
|
||||
this._commands = params[1];
|
||||
this._styles = params[2];
|
||||
}
|
||||
}
|
||||
|
||||
get changeDetectorFactories(): Function[] {
|
||||
this._init();
|
||||
return this._changeDetectorFactories;
|
||||
}
|
||||
|
||||
get styles(): string[] {
|
||||
this._init();
|
||||
return this._styles;
|
||||
}
|
||||
|
||||
get commands(): TemplateCmd[] {
|
||||
this._init();
|
||||
return this._commands;
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY_ARR = CONST_EXPR([]);
|
||||
@ -73,14 +101,14 @@ export function endElement(): TemplateCmd {
|
||||
|
||||
export class BeginComponentCmd implements TemplateCmd, IBeginElementCmd, RenderBeginComponentCmd {
|
||||
isBound: boolean = true;
|
||||
templateId: string;
|
||||
templateId: number;
|
||||
component: Type;
|
||||
constructor(public name: string, public attrNameAndValues: string[], public eventNames: string[],
|
||||
public variableNameAndValues: string[], public directives: Type[],
|
||||
public nativeShadow: boolean, public ngContentIndex: number,
|
||||
public template: CompiledTemplate) {
|
||||
this.component = directives[0];
|
||||
this.templateId = isPresent(template) ? template.id : null;
|
||||
this.templateId = template.id;
|
||||
}
|
||||
visit(visitor: CommandVisitor, context: any): any {
|
||||
return visitor.visitBeginComponent(this, context);
|
||||
|
@ -10,7 +10,7 @@ import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||
|
||||
@Injectable()
|
||||
export class ViewResolver {
|
||||
_cache: Map<Type, /*node*/ any> = new Map();
|
||||
_cache: Map<Type, ViewMetadata> = new Map();
|
||||
|
||||
resolve(component: Type): ViewMetadata {
|
||||
var view = this._cache.get(component);
|
||||
|
@ -1,14 +1,14 @@
|
||||
library angular2.src.core.metadata;
|
||||
|
||||
import "package:angular2/src/core/facade/collection.dart" show List;
|
||||
import 'package:angular2/src/core/facade/collection.dart' show List;
|
||||
import 'package:angular2/src/core/change_detection/change_detection.dart';
|
||||
import "./metadata/di.dart";
|
||||
import "./metadata/directives.dart";
|
||||
import "./metadata/view.dart";
|
||||
import './metadata/di.dart';
|
||||
import './metadata/directives.dart';
|
||||
import './metadata/view.dart';
|
||||
|
||||
export "./metadata/di.dart";
|
||||
export "./metadata/directives.dart";
|
||||
export "./metadata/view.dart";
|
||||
export './metadata/di.dart';
|
||||
export './metadata/directives.dart';
|
||||
export './metadata/view.dart';
|
||||
|
||||
/**
|
||||
* See: [DirectiveMetadata] for docs.
|
||||
@ -16,7 +16,7 @@ export "./metadata/view.dart";
|
||||
class Directive extends DirectiveMetadata {
|
||||
const Directive({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host,
|
||||
List bindings, String exportAs,
|
||||
List bindings, String exportAs, String moduleId,
|
||||
bool compileChildren: true})
|
||||
: super(
|
||||
selector: selector,
|
||||
@ -25,6 +25,7 @@ class Directive extends DirectiveMetadata {
|
||||
host: host,
|
||||
bindings: bindings,
|
||||
exportAs: exportAs,
|
||||
moduleId: moduleId,
|
||||
compileChildren: compileChildren);
|
||||
}
|
||||
|
||||
@ -33,16 +34,18 @@ class Directive extends DirectiveMetadata {
|
||||
*/
|
||||
class Component extends ComponentMetadata {
|
||||
const Component({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host,
|
||||
List bindings, String exportAs,
|
||||
List<String> events, Map<String, String> host, bool dynamicLoadable,
|
||||
List bindings, String exportAs, String moduleId,
|
||||
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
|
||||
: super(
|
||||
selector: selector,
|
||||
properties: properties,
|
||||
events: events,
|
||||
host: host,
|
||||
dynamicLoadable: dynamicLoadable,
|
||||
bindings: bindings,
|
||||
exportAs: exportAs,
|
||||
moduleId: moduleId,
|
||||
compileChildren: compileChildren,
|
||||
viewBindings: viewBindings,
|
||||
changeDetection: changeDetection);
|
||||
|
@ -139,11 +139,11 @@ export interface ViewDecorator extends TypeDecorator {
|
||||
export interface DirectiveFactory {
|
||||
(obj: {
|
||||
selector?: string, properties?: string[], events?: string[], host?: StringMap<string, string>,
|
||||
bindings?: any[], exportAs?: string, compileChildren?: boolean;
|
||||
bindings?: any[], exportAs?: string, moduleId?: string, compileChildren?: boolean;
|
||||
}): DirectiveDecorator;
|
||||
new (obj: {
|
||||
selector?: string, properties?: string[], events?: string[], host?: StringMap<string, string>,
|
||||
bindings?: any[], exportAs?: string, compileChildren?: boolean;
|
||||
bindings?: any[], exportAs?: string, moduleId?: string, compileChildren?: boolean;
|
||||
}): DirectiveMetadata;
|
||||
}
|
||||
|
||||
@ -196,8 +196,10 @@ export interface ComponentFactory {
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: any[],
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
@ -207,8 +209,10 @@ export interface ComponentFactory {
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: any[],
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {isPresent, CONST, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
import {isPresent, CONST, CONST_EXPR, Type} from 'angular2/src/core/facade/lang';
|
||||
import {InjectableMetadata} from 'angular2/src/core/di/metadata';
|
||||
import {ChangeDetectionStrategy} from 'angular2/src/core/change_detection';
|
||||
|
||||
@ -699,8 +699,29 @@ export class DirectiveMetadata extends InjectableMetadata {
|
||||
*/
|
||||
exportAs: string;
|
||||
|
||||
/**
|
||||
* The module id of the module that contains the directive.
|
||||
* Needed to be able to resolve relative urls for templates and styles.
|
||||
* In Dart, this can be determined automatically and does not need to be set.
|
||||
* In CommonJS, this can always be set to `module.id`.
|
||||
*
|
||||
* ## Simple Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: 'someDir',
|
||||
* moduleId: module.id
|
||||
* })
|
||||
* class SomeDir {
|
||||
* }
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
moduleId: string;
|
||||
|
||||
constructor({
|
||||
selector, properties, events, host, bindings, exportAs, compileChildren = true,
|
||||
selector, properties, events, host, bindings, exportAs, moduleId,
|
||||
compileChildren = true,
|
||||
}: {
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
@ -708,6 +729,7 @@ export class DirectiveMetadata extends InjectableMetadata {
|
||||
host?: StringMap<string, string>,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
} = {}) {
|
||||
super();
|
||||
@ -716,6 +738,7 @@ export class DirectiveMetadata extends InjectableMetadata {
|
||||
this.events = events;
|
||||
this.host = host;
|
||||
this.exportAs = exportAs;
|
||||
this.moduleId = moduleId;
|
||||
this.compileChildren = compileChildren;
|
||||
this.bindings = bindings;
|
||||
}
|
||||
@ -764,6 +787,34 @@ export class DirectiveMetadata extends InjectableMetadata {
|
||||
*/
|
||||
@CONST()
|
||||
export class ComponentMetadata extends DirectiveMetadata {
|
||||
/**
|
||||
* Declare that this component can be programatically loaded.
|
||||
* Every component that is used in bootstrap, routing, ... has to be
|
||||
* annotated with this.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'root',
|
||||
* dynamicLoadable: true
|
||||
* })
|
||||
* @View({
|
||||
* template: 'hello world!'
|
||||
* })
|
||||
* class RootComponent {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
dynamicLoadable: boolean;
|
||||
|
||||
|
||||
/**
|
||||
* Used by build tools to store the compiled template.
|
||||
* Not intended to be used by a user.
|
||||
*/
|
||||
compiledHostTemplate: /* CompiledTemplate */ any;
|
||||
|
||||
/**
|
||||
* Defines the used change detection strategy.
|
||||
*
|
||||
@ -817,14 +868,18 @@ export class ComponentMetadata extends DirectiveMetadata {
|
||||
*/
|
||||
viewBindings: any[];
|
||||
|
||||
constructor({selector, properties, events, host, exportAs, bindings, viewBindings,
|
||||
changeDetection = ChangeDetectionStrategy.Default, compileChildren = true}: {
|
||||
constructor({selector, properties, events, host, dynamicLoadable, compiledHostTemplate, exportAs,
|
||||
moduleId, bindings, viewBindings, changeDetection = ChangeDetectionStrategy.Default,
|
||||
compileChildren = true}: {
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
compiledHostTemplate?: any,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: any[],
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
@ -835,12 +890,15 @@ export class ComponentMetadata extends DirectiveMetadata {
|
||||
events: events,
|
||||
host: host,
|
||||
exportAs: exportAs,
|
||||
moduleId: moduleId,
|
||||
bindings: bindings,
|
||||
compileChildren: compileChildren
|
||||
});
|
||||
|
||||
this.changeDetection = changeDetection;
|
||||
this.viewBindings = viewBindings;
|
||||
this.dynamicLoadable = dynamicLoadable;
|
||||
this.compiledHostTemplate = compiledHostTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,5 +11,8 @@ export interface PlatformReflectionCapabilities {
|
||||
getter(name: string): GetterFn;
|
||||
setter(name: string): SetterFn;
|
||||
method(name: string): MethodFn;
|
||||
// TODO(tbosch): remove this method after the new compiler is done
|
||||
// (and ComponentUrlMapper as well).
|
||||
importUri(type: Type): string;
|
||||
moduleId(type: Type): string;
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ class NoReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
}
|
||||
|
||||
String importUri(Type type) => './';
|
||||
|
||||
String moduleId(Type type) => null;
|
||||
}
|
||||
|
||||
final Reflector reflector = new Reflector(new NoReflectionCapabilities());
|
||||
|
@ -5,6 +5,8 @@ import 'types.dart';
|
||||
import 'dart:mirrors';
|
||||
import 'platform_reflection_capabilities.dart';
|
||||
|
||||
var DOT_REGEX = new RegExp('\\.');
|
||||
|
||||
class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
ReflectionCapabilities([metadataReader]) {}
|
||||
|
||||
@ -315,4 +317,8 @@ class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
String importUri(Type type) {
|
||||
return '${(reflectClass(type).owner as LibraryMirror).uri}';
|
||||
}
|
||||
|
||||
String moduleId(Type type) {
|
||||
return '${MirrorSystem.getName((reflectClass(type).owner as LibraryMirror).qualifiedName).replaceAll(DOT_REGEX, "/")}';
|
||||
}
|
||||
}
|
||||
|
@ -168,4 +168,6 @@ export class ReflectionCapabilities implements PlatformReflectionCapabilities {
|
||||
|
||||
// There is not a concept of import uri in Js, but this is useful in developing Dart applications.
|
||||
importUri(type: Type): string { return './'; }
|
||||
|
||||
moduleId(type: Type): string { return null; }
|
||||
}
|
||||
|
@ -156,6 +156,8 @@ export class Reflector {
|
||||
_containsReflectionInfo(typeOrFunc) { return this._injectableInfo.has(typeOrFunc); }
|
||||
|
||||
importUri(type: Type): string { return this.reflectionCapabilities.importUri(type); }
|
||||
|
||||
moduleId(type: Type): string { return this.reflectionCapabilities.moduleId(type); }
|
||||
}
|
||||
|
||||
function _mergeMaps(target: Map<any, any>, config: StringMap<string, Function>): void {
|
||||
|
@ -409,7 +409,7 @@ export interface RenderBeginElementCmd extends RenderBeginCmd {
|
||||
|
||||
export interface RenderBeginComponentCmd extends RenderBeginElementCmd {
|
||||
nativeShadow: boolean;
|
||||
templateId: string;
|
||||
templateId: number;
|
||||
}
|
||||
|
||||
export interface RenderEmbeddedTemplateCmd extends RenderBeginElementCmd {
|
||||
|
Reference in New Issue
Block a user