refactor(compiler): cleanup and preparation for integration
- Rename `DirectiveMetadata` into `CompileDirectiveMetadata`, merge with `NormalizedDirectiveMetadata` and remove `ChangeDetectionMetadata` - Store change detector factories not as array but directly at the `CompiledTemplate` or the embedded template to make instantiation easier later on - Already analyze variable values and map them to `Directive.exportAs` - Keep the directive sort order as specified in the `@View()` annotation - Allow to clear the runtime cache in `StyleCompiler` and `TemplateCompiler` - Ignore `script` elements to match the semantics of the current compiler - Make all components dynamically loadable and remove the previously introduced property `@Component#dynamicLoadable` for now until we find a better option to configure this - Don’t allow to specify bindings in `@View#directives` and `@View#pipes` as this was never supported by the transformer (see below for the breaking change) BREAKING CHANGE: - don't support DI bindings in `@View#directives` and `@View@pipes` any more in preparation of integrating the new compiler. Use `@Directive#bindings` to reexport directives under a different token instead. Part of #3605 Closes #4314
This commit is contained in:
@ -42,7 +42,7 @@ export {
|
||||
DebugContext,
|
||||
ChangeDetectorGenConfig
|
||||
} from './interfaces';
|
||||
export {ChangeDetectionStrategy, changeDetectionStrategyFromJson} from './constants';
|
||||
export {ChangeDetectionStrategy, CHANGE_DECTION_STRATEGY_VALUES} from './constants';
|
||||
export {DynamicProtoChangeDetector} from './proto_change_detector';
|
||||
export {BindingRecord, BindingTarget} from './binding_record';
|
||||
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||
|
@ -1,11 +1,4 @@
|
||||
import {
|
||||
StringWrapper,
|
||||
normalizeBool,
|
||||
isBlank,
|
||||
serializeEnum,
|
||||
deserializeEnum
|
||||
} from 'angular2/src/core/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {StringWrapper, normalizeBool, isBlank} from 'angular2/src/core/facade/lang';
|
||||
|
||||
export enum ChangeDetectionStrategy {
|
||||
/**
|
||||
@ -48,19 +41,15 @@ export enum ChangeDetectionStrategy {
|
||||
OnPushObserve
|
||||
}
|
||||
|
||||
var strategyMap: Map<number, ChangeDetectionStrategy> = MapWrapper.createFromPairs([
|
||||
[0, ChangeDetectionStrategy.CheckOnce],
|
||||
[1, ChangeDetectionStrategy.Checked],
|
||||
[2, ChangeDetectionStrategy.CheckAlways],
|
||||
[3, ChangeDetectionStrategy.Detached],
|
||||
[4, ChangeDetectionStrategy.OnPush],
|
||||
[5, ChangeDetectionStrategy.Default],
|
||||
[6, ChangeDetectionStrategy.OnPushObserve]
|
||||
]);
|
||||
|
||||
export function changeDetectionStrategyFromJson(value: number): ChangeDetectionStrategy {
|
||||
return deserializeEnum(value, strategyMap);
|
||||
}
|
||||
export var CHANGE_DECTION_STRATEGY_VALUES = [
|
||||
ChangeDetectionStrategy.CheckOnce,
|
||||
ChangeDetectionStrategy.Checked,
|
||||
ChangeDetectionStrategy.CheckAlways,
|
||||
ChangeDetectionStrategy.Detached,
|
||||
ChangeDetectionStrategy.OnPush,
|
||||
ChangeDetectionStrategy.Default,
|
||||
ChangeDetectionStrategy.OnPushObserve
|
||||
];
|
||||
|
||||
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):
|
||||
boolean {
|
||||
|
@ -117,7 +117,6 @@ export class DirectiveResolver {
|
||||
properties: mergedProperties,
|
||||
events: mergedEvents,
|
||||
host: mergedHost,
|
||||
dynamicLoadable: dm.dynamicLoadable,
|
||||
bindings: dm.bindings,
|
||||
exportAs: dm.exportAs,
|
||||
moduleId: dm.moduleId,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {StringMap} from 'angular2/src/core/facade/collection';
|
||||
import {StringMap, MapWrapper} from 'angular2/src/core/facade/collection';
|
||||
|
||||
export enum LifecycleHooks {
|
||||
OnInit,
|
||||
@ -11,6 +11,17 @@ export enum LifecycleHooks {
|
||||
AfterViewChecked
|
||||
}
|
||||
|
||||
export var LIFECYCLE_HOOKS_VALUES = [
|
||||
LifecycleHooks.OnInit,
|
||||
LifecycleHooks.OnDestroy,
|
||||
LifecycleHooks.DoCheck,
|
||||
LifecycleHooks.OnChanges,
|
||||
LifecycleHooks.AfterContentInit,
|
||||
LifecycleHooks.AfterContentChecked,
|
||||
LifecycleHooks.AfterViewInit,
|
||||
LifecycleHooks.AfterViewChecked
|
||||
];
|
||||
|
||||
/**
|
||||
* Lifecycle hooks are guaranteed to be called in the following order:
|
||||
* - `OnChanges` (if any bindings have changed),
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from 'angular2/src/core/render/render';
|
||||
|
||||
export class CompiledTemplate {
|
||||
private _changeDetectorFactories: Function[] = null;
|
||||
private _changeDetectorFactory: Function = null;
|
||||
private _styles: string[] = null;
|
||||
private _commands: TemplateCmd[] = null;
|
||||
// Note: paramGetter is a function so that we can have cycles between templates!
|
||||
@ -19,15 +19,15 @@ export class CompiledTemplate {
|
||||
private _init() {
|
||||
if (isBlank(this._commands)) {
|
||||
var params = this._paramGetter();
|
||||
this._changeDetectorFactories = params[0];
|
||||
this._changeDetectorFactory = params[0];
|
||||
this._commands = params[1];
|
||||
this._styles = params[2];
|
||||
}
|
||||
}
|
||||
|
||||
get changeDetectorFactories(): Function[] {
|
||||
get changeDetectorFactory(): Function {
|
||||
this._init();
|
||||
return this._changeDetectorFactories;
|
||||
return this._changeDetectorFactory;
|
||||
}
|
||||
|
||||
get styles(): string[] {
|
||||
@ -69,26 +69,28 @@ export function ngContent(ngContentIndex: number): NgContentCmd {
|
||||
}
|
||||
|
||||
export interface IBeginElementCmd extends TemplateCmd, RenderBeginElementCmd {
|
||||
variableNameAndValues: string[];
|
||||
eventNames: string[];
|
||||
variableNameAndValues: Array<string | number>;
|
||||
eventTargetAndNames: string[];
|
||||
directives: Type[];
|
||||
visit(visitor: CommandVisitor, context: any): any;
|
||||
}
|
||||
|
||||
export class BeginElementCmd implements TemplateCmd, IBeginElementCmd, RenderBeginElementCmd {
|
||||
constructor(public name: string, public attrNameAndValues: string[], public eventNames: string[],
|
||||
public variableNameAndValues: string[], public directives: Type[],
|
||||
constructor(public name: string, public attrNameAndValues: string[],
|
||||
public eventTargetAndNames: string[],
|
||||
public variableNameAndValues: Array<string | number>, public directives: Type[],
|
||||
public isBound: boolean, public ngContentIndex: number) {}
|
||||
visit(visitor: CommandVisitor, context: any): any {
|
||||
return visitor.visitBeginElement(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
export function beginElement(name: string, attrNameAndValues: string[], eventNames: string[],
|
||||
variableNameAndValues: string[], directives: Type[], isBound: boolean,
|
||||
ngContentIndex: number): BeginElementCmd {
|
||||
return new BeginElementCmd(name, attrNameAndValues, eventNames, variableNameAndValues, directives,
|
||||
isBound, ngContentIndex);
|
||||
export function beginElement(name: string, attrNameAndValues: string[],
|
||||
eventTargetAndNames: string[],
|
||||
variableNameAndValues: Array<string | number>, directives: Type[],
|
||||
isBound: boolean, ngContentIndex: number): BeginElementCmd {
|
||||
return new BeginElementCmd(name, attrNameAndValues, eventTargetAndNames, variableNameAndValues,
|
||||
directives, isBound, ngContentIndex);
|
||||
}
|
||||
|
||||
export class EndElementCmd implements TemplateCmd {
|
||||
@ -103,8 +105,9 @@ export class BeginComponentCmd implements TemplateCmd, IBeginElementCmd, RenderB
|
||||
isBound: boolean = true;
|
||||
templateId: number;
|
||||
component: Type;
|
||||
constructor(public name: string, public attrNameAndValues: string[], public eventNames: string[],
|
||||
public variableNameAndValues: string[], public directives: Type[],
|
||||
constructor(public name: string, public attrNameAndValues: string[],
|
||||
public eventTargetAndNames: string[],
|
||||
public variableNameAndValues: Array<string | number>, public directives: Type[],
|
||||
public nativeShadow: boolean, public ngContentIndex: number,
|
||||
public template: CompiledTemplate) {
|
||||
this.component = directives[0];
|
||||
@ -115,11 +118,11 @@ export class BeginComponentCmd implements TemplateCmd, IBeginElementCmd, RenderB
|
||||
}
|
||||
}
|
||||
|
||||
export function beginComponent(name: string, attrNameAnsValues: string[], eventNames: string[],
|
||||
variableNameAndValues: string[], directives: Type[],
|
||||
nativeShadow: boolean, ngContentIndex: number,
|
||||
template: CompiledTemplate): BeginComponentCmd {
|
||||
return new BeginComponentCmd(name, attrNameAnsValues, eventNames, variableNameAndValues,
|
||||
export function beginComponent(
|
||||
name: string, attrNameAnsValues: string[], eventTargetAndNames: string[],
|
||||
variableNameAndValues: Array<string | number>, directives: Type[], nativeShadow: boolean,
|
||||
ngContentIndex: number, template: CompiledTemplate): BeginComponentCmd {
|
||||
return new BeginComponentCmd(name, attrNameAnsValues, eventTargetAndNames, variableNameAndValues,
|
||||
directives, nativeShadow, ngContentIndex, template);
|
||||
}
|
||||
|
||||
@ -135,10 +138,10 @@ export class EmbeddedTemplateCmd implements TemplateCmd, IBeginElementCmd,
|
||||
RenderEmbeddedTemplateCmd {
|
||||
isBound: boolean = true;
|
||||
name: string = null;
|
||||
eventNames: string[] = EMPTY_ARR;
|
||||
eventTargetAndNames: string[] = EMPTY_ARR;
|
||||
constructor(public attrNameAndValues: string[], public variableNameAndValues: string[],
|
||||
public directives: Type[], public isMerged: boolean, public ngContentIndex: number,
|
||||
public children: TemplateCmd[]) {}
|
||||
public changeDetectorFactory: Function, public children: TemplateCmd[]) {}
|
||||
visit(visitor: CommandVisitor, context: any): any {
|
||||
return visitor.visitEmbeddedTemplate(this, context);
|
||||
}
|
||||
@ -146,20 +149,13 @@ export class EmbeddedTemplateCmd implements TemplateCmd, IBeginElementCmd,
|
||||
|
||||
export function embeddedTemplate(attrNameAndValues: string[], variableNameAndValues: string[],
|
||||
directives: Type[], isMerged: boolean, ngContentIndex: number,
|
||||
children: TemplateCmd[]): EmbeddedTemplateCmd {
|
||||
changeDetectorFactory: Function, children: TemplateCmd[]):
|
||||
EmbeddedTemplateCmd {
|
||||
return new EmbeddedTemplateCmd(attrNameAndValues, variableNameAndValues, directives, isMerged,
|
||||
ngContentIndex, children);
|
||||
ngContentIndex, changeDetectorFactory, children);
|
||||
}
|
||||
|
||||
export interface CommandVisitor extends RenderCommandVisitor {
|
||||
visitText(cmd: TextCmd, context: any): any;
|
||||
visitNgContent(cmd: NgContentCmd, context: any): any;
|
||||
visitBeginElement(cmd: BeginElementCmd, context: any): any;
|
||||
visitEndElement(context: any): any;
|
||||
visitBeginComponent(cmd: BeginComponentCmd, context: any): any;
|
||||
visitEndComponent(context: any): any;
|
||||
visitEmbeddedTemplate(cmd: EmbeddedTemplateCmd, context: any): any;
|
||||
}
|
||||
export interface CommandVisitor extends RenderCommandVisitor {}
|
||||
|
||||
export function visitAllCommands(visitor: CommandVisitor, cmds: TemplateCmd[],
|
||||
context: any = null) {
|
||||
|
@ -36,7 +36,7 @@ class Directive extends DirectiveMetadata {
|
||||
*/
|
||||
class Component extends ComponentMetadata {
|
||||
const Component({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host, bool dynamicLoadable,
|
||||
List<String> events, Map<String, String> host,
|
||||
List bindings, String exportAs, String moduleId,
|
||||
Map<String, dynamic> queries,
|
||||
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
|
||||
@ -45,7 +45,6 @@ class Component extends ComponentMetadata {
|
||||
properties: properties,
|
||||
events: events,
|
||||
host: host,
|
||||
dynamicLoadable: dynamicLoadable,
|
||||
bindings: bindings,
|
||||
exportAs: exportAs,
|
||||
moduleId: moduleId,
|
||||
|
@ -76,8 +76,8 @@ export interface ComponentDecorator extends TypeDecorator {
|
||||
View(obj: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any | any[]>,
|
||||
pipes?: Array<Type | any | any[]>,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
renderer?: string,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
@ -96,8 +96,8 @@ export interface ViewDecorator extends TypeDecorator {
|
||||
View(obj: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any | any[]>,
|
||||
pipes?: Array<Type | any | any[]>,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
renderer?: string,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
@ -218,7 +218,6 @@ export interface ComponentFactory {
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
@ -232,7 +231,6 @@ export interface ComponentFactory {
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
@ -290,7 +288,8 @@ export interface ViewFactory {
|
||||
(obj: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any | any[]>,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
encapsulation?: ViewEncapsulation,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
@ -298,7 +297,8 @@ export interface ViewFactory {
|
||||
new (obj: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any | any[]>,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
encapsulation?: ViewEncapsulation,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
|
@ -826,27 +826,6 @@ 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;
|
||||
|
||||
/**
|
||||
* Defines the used change detection strategy.
|
||||
*
|
||||
@ -900,22 +879,21 @@ export class ComponentMetadata extends DirectiveMetadata {
|
||||
*/
|
||||
viewBindings: any[];
|
||||
|
||||
constructor({selector, properties, events, host, dynamicLoadable, exportAs, moduleId, bindings,
|
||||
queries, viewBindings, changeDetection = ChangeDetectionStrategy.Default,
|
||||
compileChildren = true}: {
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
dynamicLoadable?: boolean,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: any[],
|
||||
queries?: StringMap<string, any>,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
} = {}) {
|
||||
constructor({selector, properties, events, host, exportAs, moduleId, bindings, viewBindings,
|
||||
changeDetection = ChangeDetectionStrategy.Default, queries, compileChildren = true}:
|
||||
{
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
moduleId?: string,
|
||||
compileChildren?: boolean,
|
||||
viewBindings?: any[],
|
||||
queries?: StringMap<string, any>,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
} = {}) {
|
||||
super({
|
||||
selector: selector,
|
||||
properties: properties,
|
||||
@ -930,7 +908,6 @@ export class ComponentMetadata extends DirectiveMetadata {
|
||||
|
||||
this.changeDetection = changeDetection;
|
||||
this.viewBindings = viewBindings;
|
||||
this.dynamicLoadable = dynamicLoadable;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,12 +82,9 @@ export class ViewMetadata {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
// TODO(tbosch): use Type | Binding | any[] when Dart supports union types,
|
||||
// as otherwise we would need to import Binding type and Dart would warn
|
||||
// for an unused import.
|
||||
directives: Array<Type | any | any[]>;
|
||||
directives: Array<Type | any[]>;
|
||||
|
||||
pipes: Array<Type | any | any[]>;
|
||||
pipes: Array<Type | any[]>;
|
||||
|
||||
/**
|
||||
* Specify how the template and the styles should be encapsulated.
|
||||
@ -100,8 +97,8 @@ export class ViewMetadata {
|
||||
constructor({templateUrl, template, directives, pipes, encapsulation, styles, styleUrls}: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any | any[]>,
|
||||
pipes?: Array<Type | any | any[]>,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
encapsulation?: ViewEncapsulation,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {isPresent, isBlank, RegExpWrapper, deserializeEnum} from 'angular2/src/core/facade/lang';
|
||||
import {isPresent, isBlank, RegExpWrapper} from 'angular2/src/core/facade/lang';
|
||||
import {Promise} from 'angular2/src/core/facade/async';
|
||||
import {Map, MapWrapper, StringMap, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {
|
||||
@ -309,11 +309,8 @@ export enum ViewEncapsulation {
|
||||
None
|
||||
}
|
||||
|
||||
var encapsulationMap: Map<number, ViewEncapsulation> = MapWrapper.createFromPairs(
|
||||
[[0, ViewEncapsulation.Emulated], [1, ViewEncapsulation.Native], [2, ViewEncapsulation.None]]);
|
||||
export function viewEncapsulationFromJson(value: number): ViewEncapsulation {
|
||||
return deserializeEnum(value, encapsulationMap);
|
||||
}
|
||||
export var VIEW_ENCAPSULATION_VALUES =
|
||||
[ViewEncapsulation.Emulated, ViewEncapsulation.Native, ViewEncapsulation.None];
|
||||
|
||||
export class ViewDefinition {
|
||||
componentId: string;
|
||||
@ -409,7 +406,7 @@ export interface RenderNgContentCmd extends RenderBeginCmd { ngContentIndex: num
|
||||
export interface RenderBeginElementCmd extends RenderBeginCmd {
|
||||
name: string;
|
||||
attrNameAndValues: string[];
|
||||
eventNames: string[];
|
||||
eventTargetAndNames: string[];
|
||||
}
|
||||
|
||||
export interface RenderBeginComponentCmd extends RenderBeginElementCmd {
|
||||
@ -422,15 +419,14 @@ export interface RenderEmbeddedTemplateCmd extends RenderBeginElementCmd {
|
||||
children: RenderTemplateCmd[];
|
||||
}
|
||||
|
||||
// TODO(tbosch): change ts2dart to allow to use `CMD` as type in these methods!
|
||||
export interface RenderCommandVisitor {
|
||||
visitText /*<CMD extends RenderTextCmd>*/ (cmd: any, context: any): any;
|
||||
visitNgContent /*<CMD extends RenderNgContentCmd>*/ (cmd: any, context: any): any;
|
||||
visitBeginElement /*<CMD extends RenderBeginElementCmd>*/ (cmd: any, context: any): any;
|
||||
visitText(cmd: any, context: any): any;
|
||||
visitNgContent(cmd: any, context: any): any;
|
||||
visitBeginElement(cmd: any, context: any): any;
|
||||
visitEndElement(context: any): any;
|
||||
visitBeginComponent /*<CMD extends RenderBeginComponentCmd>*/ (cmd: any, context: any): any;
|
||||
visitBeginComponent(cmd: any, context: any): any;
|
||||
visitEndComponent(context: any): any;
|
||||
visitEmbeddedTemplate /*<CMD extends RenderEmbeddedTemplateCmd>*/ (cmd: any, context: any): any;
|
||||
visitEmbeddedTemplate(cmd: any, context: any): any;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user