diff --git a/modules/benchmarks/src/largetable/render3/table.ts b/modules/benchmarks/src/largetable/render3/table.ts index 702b83a456..35553891c5 100644 --- a/modules/benchmarks/src/largetable/render3/table.ts +++ b/modules/benchmarks/src/largetable/render3/table.ts @@ -7,7 +7,7 @@ */ import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as detectChanges, ɵe as e, ɵs as s, ɵt as t, ɵv as v} from '@angular/core'; -import {ComponentDef} from '@angular/core/src/render3/public_interfaces'; +import {ComponentDef} from '@angular/core/src/render3/definition_interfaces'; import {TableCell, buildTable, emptyTable} from '../util'; diff --git a/modules/benchmarks/src/tree/render3/tree.ts b/modules/benchmarks/src/tree/render3/tree.ts index f786442f5d..2af31bf70e 100644 --- a/modules/benchmarks/src/tree/render3/tree.ts +++ b/modules/benchmarks/src/tree/render3/tree.ts @@ -7,7 +7,7 @@ */ import {ɵC as C, ɵD as D, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵb1 as b1, ɵc as c, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵp as p, ɵs as s, ɵt as t, ɵv as v} from '@angular/core'; -import {ComponentDef} from '@angular/core/src/render3/public_interfaces'; +import {ComponentDef} from '@angular/core/src/render3/definition_interfaces'; import {TreeNode, buildTree, emptyTree} from '../util'; diff --git a/packages/core/src/render3/component.ts b/packages/core/src/render3/component.ts index a4e21f3bd6..cd6dd9dfb5 100644 --- a/packages/core/src/render3/component.ts +++ b/packages/core/src/render3/component.ts @@ -8,12 +8,14 @@ // We are temporarily importing the existing viewEngine from core so we can be sure we are // correctly implementing its interfaces for backwards compatibility. -import * as viewEngine from '../core'; +import {Injector} from '../di/injector'; +import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory'; +import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref'; import {assertNotNull} from './assert'; +import {ComponentDef, ComponentType} from './definition_interfaces'; import {NG_HOST_SYMBOL, createError, createViewState, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions'; -import {LElement} from './l_node'; -import {ComponentDef, ComponentType} from './public_interfaces'; +import {LElement} from './interfaces'; import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './renderer'; import {notImplemented, stringify} from './util'; @@ -32,7 +34,7 @@ export interface CreateComponentOptions { host?: RElement|string; /** Module injector for the component. If unspecified, the injector will be NULL_INJECTOR. */ - injector?: viewEngine.Injector; + injector?: Injector; /** * List of features to be applied to the created component. Features are simply @@ -51,7 +53,7 @@ export interface CreateComponentOptions { * @param options Optional parameters which control bootstrapping */ export function createComponentRef( - componentType: ComponentType, opts: CreateComponentOptions): viewEngine.ComponentRef { + componentType: ComponentType, opts: CreateComponentOptions): viewEngine_ComponentRef { const component = renderComponent(componentType, opts); const hostView = createViewRef(() => detectChanges(component), component); return { @@ -78,7 +80,7 @@ function createViewRef(detectChanges: () => void, context: T): EmbeddedViewRe return addDestroyable(new EmbeddedViewRef(detectChanges), context); } -class EmbeddedViewRef implements viewEngine.EmbeddedViewRef { +class EmbeddedViewRef implements viewEngine_EmbeddedViewRef { // TODO: rootNodes should be replaced when properly implemented rootNodes = null !; context: T; @@ -147,7 +149,7 @@ function addDestroyable(obj: any, context: C): T&DestroyRef { // TODO: A hack to not pull in the NullInjector from @angular/core. -export const NULL_INJECTOR: viewEngine.Injector = { +export const NULL_INJECTOR: Injector = { get: (token: any, notFoundValue?: any) => { throw new Error('NullInjector: Not found: ' + stringify(token)); } diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts new file mode 100644 index 0000000000..9908979e9a --- /dev/null +++ b/packages/core/src/render3/definition.ts @@ -0,0 +1,87 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {RendererType2} from '../render/api'; +import {Type} from '../type'; +import {resolveRendererType2} from '../view/util'; + +import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './definition_interfaces'; +import {componentRefresh, diPublic} from './instructions'; + + + +/** + * Create a component definition object. + * + * + * # Example + * ``` + * class MyDirective { + * // Generated by Angular Template Compiler + * // [Symbol] syntax will not be supported by TypeScript until v2.7 + * static [COMPONENT_DEF_SYMBOL] = defineComponent({ + * ... + * }); + * } + * ``` + */ +export function defineComponent(componentDefinition: ComponentDefArgs): ComponentDef { + const def = >{ + type: componentDefinition.type, + diPublic: null, + n: componentDefinition.factory, + tag: (componentDefinition as ComponentDefArgs).tag || null !, + template: (componentDefinition as ComponentDefArgs).template || null !, + r: componentDefinition.refresh || + function(d: number, e: number) { componentRefresh(d, e, componentDefinition.template); }, + inputs: invertObject(componentDefinition.inputs), + outputs: invertObject(componentDefinition.outputs), + methods: invertObject(componentDefinition.methods), + rendererType: resolveRendererType2(componentDefinition.rendererType) || null, + }; + const feature = componentDefinition.features; + feature && feature.forEach((fn) => fn(def)); + return def; +} + +export function NgOnChangesFeature(definition: DirectiveDef) { + // TODO: implement. See: https://app.asana.com/0/443577627818617/465170715764659 +} + +export function PublicFeature(definition: DirectiveDef) { + definition.diPublic = diPublic; +} + +const EMPTY = {}; + +/** Swaps the keys and values of an object. */ +function invertObject(obj: any): any { + if (obj == null) return EMPTY; + const newObj: any = {}; + for (let minifiedKey in obj) { + newObj[obj[minifiedKey]] = minifiedKey; + } + return newObj; +} + +/** + * Create a directive definition object. + * + * # Example + * ``` + * class MyDirective { + * // Generated by Angular Template Compiler + * // [Symbol] syntax will not be supported by TypeScript until v2.7 + * static [DIRECTIVE_DEF_SYMBOL] = defineDirective({ + * ... + * }); + * } + * ``` + */ +export const defineDirective = defineComponent as(directiveDefinition: DirectiveDefArgs) => + DirectiveDef; diff --git a/packages/core/src/render3/public_interfaces.ts b/packages/core/src/render3/definition_interfaces.ts similarity index 61% rename from packages/core/src/render3/public_interfaces.ts rename to packages/core/src/render3/definition_interfaces.ts index 6079ccf5ae..32931cf988 100644 --- a/packages/core/src/render3/public_interfaces.ts +++ b/packages/core/src/render3/definition_interfaces.ts @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {RendererType2, Type} from '../core'; +import {RendererType2} from '../render/api'; +import {Type} from '../type'; import {resolveRendererType2} from '../view/util'; -import {componentRefresh, diPublic} from './instructions'; @@ -78,7 +78,7 @@ export interface DirectiveDef { * @param directiveIndex index of the directive in the containing template * @param elementIndex index of an host element for a given directive. */ - r(this: DirectiveDef, directiveIndex: number, elementIndex: number): void; + r(directiveIndex: number, elementIndex: number): void; } export interface ComponentDef extends DirectiveDef { @@ -93,7 +93,7 @@ export interface ComponentDef extends DirectiveDef { * @param directiveIndex index of the directive in the containing template * @param elementIndex index of an host element for a given component. */ - r(this: ComponentDef, directiveIndex: number, elementIndex: number): void; + r(directiveIndex: number, elementIndex: number): void; /** * The tag name which should be used by the component. @@ -120,7 +120,7 @@ export interface ComponentDef extends DirectiveDef { export interface DirectiveDefArgs { type: Type; factory: () => T; - refresh?: (this: DirectiveDef, directiveIndex: number, elementIndex: number) => void; + refresh?: (directiveIndex: number, elementIndex: number) => void; inputs?: {[P in keyof T]?: string}; outputs?: {[P in keyof T]?: string}; methods?: {[P in keyof T]?: string}; @@ -130,80 +130,10 @@ export interface DirectiveDefArgs { export interface ComponentDefArgs extends DirectiveDefArgs { tag: string; template: ComponentTemplate; - refresh?: (this: ComponentDef, directiveIndex: number, elementIndex: number) => void; + refresh?: (directiveIndex: number, elementIndex: number) => void; features?: ComponentDefFeature[]; rendererType?: RendererType2; } export type DirectiveDefFeature = (directiveDef: DirectiveDef) => void; export type ComponentDefFeature = (directiveDef: DirectiveDef) => void; - -/** - * Create a component definition object. - * - * - * # Example - * ``` - * class MyDirective { - * // Generated by Angular Template Compiler - * // [Symbol] syntax will not be supported by TypeScript until v2.7 - * static [COMPONENT_DEF_SYMBOL] = defineComponent({ - * ... - * }); - * } - * ``` - */ -export function defineComponent(componentDefinition: ComponentDefArgs): ComponentDef { - const def = >{ - type: componentDefinition.type, - diPublic: null, - n: componentDefinition.factory, - tag: (componentDefinition as ComponentDefArgs).tag || null !, - template: (componentDefinition as ComponentDefArgs).template || null !, - r: componentDefinition.refresh || componentRefresh, - inputs: invertObject(componentDefinition.inputs), - outputs: invertObject(componentDefinition.outputs), - methods: invertObject(componentDefinition.methods), - rendererType: resolveRendererType2(componentDefinition.rendererType) || null, - }; - const feature = componentDefinition.features; - feature && feature.forEach((fn) => fn(def)); - return def; -} - -export function NgOnChangesFeature(definition: DirectiveDef) { - // TODO: implement. See: https://app.asana.com/0/443577627818617/465170715764659 -} - -export function PublicFeature(definition: DirectiveDef) { - definition.diPublic = diPublic; -} - -const EMPTY = {}; - -/** Swaps the keys and values of an object. */ -function invertObject(obj: any): any { - if (obj == null) return EMPTY; - const newObj: any = {}; - for (let minifiedKey in obj) { - newObj[obj[minifiedKey]] = minifiedKey; - } - return newObj; -} - -/** - * Create a directive definition object. - * - * # Example - * ``` - * class MyDirective { - * // Generated by Angular Template Compiler - * // [Symbol] syntax will not be supported by TypeScript until v2.7 - * static [DIRECTIVE_DEF_SYMBOL] = defineDirective({ - * ... - * }); - * } - * ``` - */ -export const defineDirective = defineComponent as(directiveDefinition: DirectiveDefArgs) => - DirectiveDef; diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index 6ad9eb27f7..2833a40190 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -6,13 +6,20 @@ * found in the LICENSE file at https://angular.io/license */ -// We are temporarily importing the existing viewEngine from core so we can be sure we are +// We are temporarily importing the existing viewEngine_from core so we can be sure we are // correctly implementing its interfaces for backwards compatibility. -import * as viewEngine from '../core'; +import {Injector} from '../di/injector'; +import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory'; +import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref'; +import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory'; +import {TemplateRef as viewEngine_TemplateRef} from '../linker/template_ref'; +import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref'; +import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref'; +import {Type} from '../type'; -import {LContainer, LElement, LNodeFlags, LNodeInjector} from './l_node'; +import {ComponentTemplate, DirectiveDef} from './definition_interfaces'; +import {LContainer, LElement, LNodeFlags, LNodeInjector} from './interfaces'; import {assertNodeType} from './node_assert'; -import {ComponentTemplate, DirectiveDef} from './public_interfaces'; import {notImplemented, stringify} from './util'; @@ -41,7 +48,7 @@ let nextNgElementId = 0; * @param injector The node injector in which the directive should be registered * @param type The directive to register */ -export function bloomAdd(injector: LNodeInjector, type: viewEngine.Type): void { +export function bloomAdd(injector: LNodeInjector, type: Type): void { let id: number|undefined = (type as any)[NG_ELEMENT_ID]; // Set a unique ID on the directive type, so if something tries to inject the directive, @@ -161,7 +168,7 @@ export function diPublicInInjector(di: LNodeInjector, def: DirectiveDef): v * @returns The instance found */ export function getOrCreateInjectable( - di: LNodeInjector, token: viewEngine.Type, flags?: InjectFlags): T { + di: LNodeInjector, token: Type, flags?: InjectFlags): T { const bloomHash = bloomHashBit(token); // If the token has a bloom hash, then it is a directive that is public to the injection system @@ -234,7 +241,7 @@ export function getOrCreateInjectable( * @param type The directive type * @returns The bloom bit to check for the directive */ -function bloomHashBit(type: viewEngine.Type): number|null { +function bloomHashBit(type: Type): number|null { let id: number|undefined = (type as any)[NG_ELEMENT_ID]; return typeof id === 'number' ? id % BLOOM_SIZE : null; } @@ -300,12 +307,12 @@ export function bloomFindPossibleInjector( * @param di The node injector where we should store a created ElementRef * @returns The ElementRef instance to use */ -export function getOrCreateElementRef(di: LNodeInjector): viewEngine.ElementRef { +export function getOrCreateElementRef(di: LNodeInjector): viewEngine_ElementRef { return di.elementRef || (di.elementRef = new ElementRef(di.node.native)); } /** A ref to a node's native element. */ -class ElementRef implements viewEngine.ElementRef { +class ElementRef implements viewEngine_ElementRef { readonly nativeElement: any; constructor(nativeElement: any) { this.nativeElement = nativeElement; } } @@ -317,7 +324,7 @@ class ElementRef implements viewEngine.ElementRef { * @param di The node injector where we should store a created TemplateRef * @returns The TemplateRef instance to use */ -export function getOrCreateTemplateRef(di: LNodeInjector): viewEngine.TemplateRef { +export function getOrCreateTemplateRef(di: LNodeInjector): viewEngine_TemplateRef { ngDevMode && assertNodeType(di.node, LNodeFlags.Container); const data = (di.node as LContainer).data; return di.templateRef || @@ -325,14 +332,14 @@ export function getOrCreateTemplateRef(di: LNodeInjector): viewEngine.Templat } /** A ref to a particular template. */ -class TemplateRef implements viewEngine.TemplateRef { - readonly elementRef: viewEngine.ElementRef; +class TemplateRef implements viewEngine_TemplateRef { + readonly elementRef: viewEngine_ElementRef; - constructor(elementRef: viewEngine.ElementRef, template: ComponentTemplate|null) { + constructor(elementRef: viewEngine_ElementRef, template: ComponentTemplate|null) { this.elementRef = elementRef; } - createEmbeddedView(context: T): viewEngine.EmbeddedViewRef { throw notImplemented(); } + createEmbeddedView(context: T): viewEngine_EmbeddedViewRef { throw notImplemented(); } } /** @@ -341,7 +348,7 @@ class TemplateRef implements viewEngine.TemplateRef { * * @returns The ViewContainerRef instance to use */ -export function getOrCreateContainerRef(di: LNodeInjector): viewEngine.ViewContainerRef { +export function getOrCreateContainerRef(di: LNodeInjector): viewEngine_ViewContainerRef { return di.viewContainerRef || (di.viewContainerRef = new ViewContainerRef(di.node as LContainer)); } @@ -349,34 +356,34 @@ export function getOrCreateContainerRef(di: LNodeInjector): viewEngine.ViewConta * A ref to a container that enables adding and removing views from that container * imperatively. */ -class ViewContainerRef implements viewEngine.ViewContainerRef { - element: viewEngine.ElementRef; - injector: viewEngine.Injector; - parentInjector: viewEngine.Injector; +class ViewContainerRef implements viewEngine_ViewContainerRef { + element: viewEngine_ElementRef; + injector: Injector; + parentInjector: Injector; constructor(node: LContainer) {} clear(): void { throw notImplemented(); } - get(index: number): viewEngine.ViewRef|null { throw notImplemented(); } + get(index: number): viewEngine_ViewRef|null { throw notImplemented(); } length: number; createEmbeddedView( - templateRef: viewEngine.TemplateRef, context?: C|undefined, - index?: number|undefined): viewEngine.EmbeddedViewRef { + templateRef: viewEngine_TemplateRef, context?: C|undefined, + index?: number|undefined): viewEngine_EmbeddedViewRef { throw notImplemented(); } createComponent( - componentFactory: viewEngine.ComponentFactory, index?: number|undefined, - injector?: viewEngine.Injector|undefined, projectableNodes?: any[][]|undefined, - ngModule?: viewEngine.NgModuleRef|undefined): viewEngine.ComponentRef { + componentFactory: viewEngine_ComponentFactory, index?: number|undefined, + injector?: Injector|undefined, projectableNodes?: any[][]|undefined, + ngModule?: viewEngine_NgModuleRef|undefined): viewEngine_ComponentRef { throw notImplemented(); } - insert(viewRef: viewEngine.ViewRef, index?: number|undefined): viewEngine.ViewRef { + insert(viewRef: viewEngine_ViewRef, index?: number|undefined): viewEngine_ViewRef { throw notImplemented(); } - move(viewRef: viewEngine.ViewRef, currentIndex: number): viewEngine.ViewRef { + move(viewRef: viewEngine_ViewRef, currentIndex: number): viewEngine_ViewRef { throw notImplemented(); } - indexOf(viewRef: viewEngine.ViewRef): number { throw notImplemented(); } + indexOf(viewRef: viewEngine_ViewRef): number { throw notImplemented(); } remove(index?: number|undefined): void { throw notImplemented(); } - detach(index?: number|undefined): viewEngine.ViewRef|null { throw notImplemented(); } + detach(index?: number|undefined): viewEngine_ViewRef|null { throw notImplemented(); } } diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index f5373e1440..b5401934af 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -7,7 +7,9 @@ */ import {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent} from './component'; -import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, NgOnChangesFeature, PublicFeature, defineComponent, defineDirective} from './public_interfaces'; +import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective} from './definition'; +import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags} from './definition_interfaces'; + // Naming scheme: // - Capital letters are for creating things: T(Text), E(Element), D(Directive), V(View), diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index a10a99b3b7..058b95835e 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -8,17 +8,19 @@ import './ng_dev_mode'; -import {ElementRef, TemplateRef, Type, ViewContainerRef} from '../core'; +import {ElementRef} from '../linker/element_ref'; +import {TemplateRef} from '../linker/template_ref'; +import {ViewContainerRef} from '../linker/view_container_ref'; +import {Type} from '../type'; import {assertEqual, assertLessThan, assertNotEqual, assertNotNull} from './assert'; -import {ContainerState, CssSelector, ProjectionState, QueryReadType, QueryState, ViewState} from './interfaces'; -import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LProjection, LText, LView} from './l_node'; +import {ContainerState, CssSelector, LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LProjection, LText, LView, ProjectionState, QueryReadType, QueryState, ViewState} from './interfaces'; import {NgStaticData, LNodeStatic, LContainerStatic, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './l_node_static'; import {assertNodeType} from './node_assert'; import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation'; import {isNodeMatchingSelector} from './node_selector_matcher'; -import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './public_interfaces'; +import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef} from './definition_interfaces'; import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di'; import {QueryList, QueryState_} from './query'; import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './renderer'; @@ -82,7 +84,9 @@ let ngStaticData: NgStaticData; /** * State of the current view being processed. */ -let currentView: ViewState = createViewState(null !, null !, []); +let currentView: ViewState; +// The initialization has to be after the `let`, otherwise `createViewState` can't see `let`. +currentView = createViewState(null !, null !, []); let currentQuery: QueryState|null; @@ -1138,8 +1142,7 @@ export function viewEnd(): void { export const componentRefresh: (directiveIndex: number, elementIndex: number, template: ComponentTemplate) => void = function( - this: undefined | {template: ComponentTemplate}, directiveIndex: number, - elementIndex: number, template: ComponentTemplate) { + directiveIndex: number, elementIndex: number, template: ComponentTemplate) { ngDevMode && assertDataInRange(elementIndex); const element = data ![elementIndex] as LElement; ngDevMode && assertNodeType(element, LNodeFlags.Element); @@ -1150,7 +1153,7 @@ export const componentRefresh: const directive = data[directiveIndex]; const oldView = enterView(hostView, element); try { - (template || this !.template)(directive, creationMode); + template(directive, creationMode); } finally { leaveView(oldView); } @@ -1284,18 +1287,11 @@ export function addToViewTree(state: T): T { //// Bindings ////////////////////////// -/** - * The type of the NO_CHANGE constant, which can never be structurally matched - * because of its private member. - */ -export declare class NO_CHANGE_TYPE { +export interface NO_CHANGE { // This is a brand that ensures that this type can never match anything else - private _; + brand: 'NO_CHANGE'; } -// This is an alias for NO_CHANGE_TYPE for brevity throughout the codebase. -export type NO_CHANGE = typeof NO_CHANGE_TYPE; - /** A special value which designates that a value has not changed. */ export const NO_CHANGE = {} as NO_CHANGE; diff --git a/packages/core/src/render3/interfaces.ts b/packages/core/src/render3/interfaces.ts index f0db9cefe4..cbab9e4418 100644 --- a/packages/core/src/render3/interfaces.ts +++ b/packages/core/src/render3/interfaces.ts @@ -6,12 +6,274 @@ * found in the LICENSE file at https://angular.io/license */ -import {QueryList, Type} from '../core'; +import {Injector} from '../di/injector'; +import {ElementRef} from '../linker/element_ref'; +import {QueryList} from '../linker/query_list'; +import {TemplateRef} from '../linker/template_ref'; +import {ViewContainerRef} from '../linker/view_container_ref'; +import {Type} from '../type'; -import {LContainer, LElement, LNode, LText, LView} from './l_node'; +import {ComponentTemplate, DirectiveDef} from './definition_interfaces'; import {LNodeStatic} from './l_node_static'; -import {ComponentTemplate, DirectiveDef} from './public_interfaces'; -import {Renderer3} from './renderer'; +import {RComment, RElement, RText, Renderer3} from './renderer'; + + + +/** + * LNodeFlags corresponds to the LNode.flags property. It contains information + * on how to map a particular set of bits in LNode.flags to the node type, directive + * count, or directive starting index. + * + * For example, if you wanted to check the type of a certain node, you would mask + * node.flags with TYPE_MASK and compare it to the value for a certain node type. e.g: + * + *```ts + * if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {...} + *``` + */ +export const enum LNodeFlags { + Container = 0b00, + Projection = 0b01, + View = 0b10, + Element = 0b11, + ViewOrElement = 0b10, + SIZE_SKIP = 0b100, + SIZE_SHIFT = 2, + INDX_SHIFT = 12, + TYPE_MASK = 0b00000000000000000000000000000011, + SIZE_MASK = 0b00000000000000000000111111111100, + INDX_MASK = 0b11111111111111111111000000000000 +} + +/** + * LNode is an internal data structure which is used for the incremental DOM algorithm. + * The "L" stands for "Logical" to differentiate between `RNodes` (actual rendered DOM + * node) and our logical representation of DOM nodes, `LNodes`. + * + * The data structure is optimized for speed and size. + * + * In order to be fast, all subtypes of `LNode` should have the same shape. + * Because size of the `LNode` matters, many fields have multiple roles depending + * on the `LNode` subtype. + * + * See: https://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching + * + * NOTE: This is a private data structure and should not be exported by any of the + * instructions. + */ +export interface LNode { + /** + * This number stores three values using its bits: + * + * - the type of the node (first 2 bits) + * - the number of directives on that node (next 10 bits) + * - the starting index of the node's directives in the directives array (last 20 bits). + * + * The latter two values are necessary so DI can effectively search the directives associated + * with a node without searching the whole directives array. + */ + flags: LNodeFlags; + + /** + * The associated DOM node. Storing this allows us to: + * - append children to their element parents in the DOM (e.g. `parent.native.appendChild(...)`) + * - retrieve the sibling elements of text nodes whose creation / insertion has been delayed + * - mark locations where child views should be inserted (for containers) + */ + readonly native: RElement|RText|RComment|null; + + /** + * We need a reference to a node's parent so we can append the node to its parent's native + * element at the appropriate time. + */ + readonly parent: LNode|null; + + /** + * First child of the current node. + */ + child: LNode|null; + + /** + * The next sibling node. Necessary so we can propagate through the root nodes of a view + * to insert them or remove them from the DOM. + */ + next: LNode|null; + + /** + * If regular LElement, then `data` will be null. + * If LElement with component, then `data` contains ViewState. + * If LView, then `data` contains the ViewState. + * If LContainer, then `data` contains ContainerState. + * If LProjection, then `data` contains ProjectionState. + */ + readonly data: ViewState|ContainerState|ProjectionState|null; + + + /** + * Each node belongs to a view. + * + * When the injector is walking up a tree, it needs access to the `directives` (part of view). + */ + readonly view: ViewState; + + /** The injector associated with this node. Necessary for DI. */ + nodeInjector: LNodeInjector|null; + + /** + * Optional `QueryState` used for tracking queries. + * + * If present the node creation/updates are reported to the `QueryState`. + */ + query: QueryState|null; + + /** + * Pointer to the corresponding LNodeStatic object, which stores static + * data about this node. + */ + staticData: LNodeStatic|null; +} + + +/** LNode representing an element. */ +export interface LElement extends LNode { + /** The DOM element associated with this node. */ + readonly native: RElement; + + child: LContainer|LElement|LText|LProjection|null; + next: LContainer|LElement|LText|LProjection|null; + + /** If Component than data has ViewState (light DOM) */ + readonly data: ViewState|null; + + /** LElement nodes can be inside other LElement nodes or inside LViews. */ + readonly parent: LElement|LView; +} + +/** LNode representing a #text node. */ +export interface LText extends LNode { + /** The text node associated with this node. */ + native: RText; + child: null; + next: LContainer|LElement|LText|LProjection|null; + + /** LText nodes can be inside LElement nodes or inside LViews. */ + readonly parent: LElement|LView; + readonly data: null; +} + +/** + * Abstract node which contains root nodes of a view. + */ +export interface LView extends LNode { + readonly native: null; + child: LContainer|LElement|LText|LProjection|null; + next: LView|null; + + /** LView nodes can only be added to LContainers. */ + readonly parent: LContainer|null; + readonly data: ViewState; +} + +/** + * Abstract node container which contains other views. + */ +export interface LContainer extends LNode { + /** + * This comment node is appended to the container's parent element to mark where + * in the DOM the container's child views should be added. + * + * If the container is a root node of a view, this comment will not be appended + * until the parent view is processed. + */ + readonly native: RComment; + readonly data: ContainerState; + child: null; + next: LContainer|LElement|LText|LProjection|null; + + /** Containers can be added to elements or views. */ + readonly parent: LElement|LView|null; +} + + +export interface LProjection extends LNode { + readonly native: null; + child: null; + next: LContainer|LElement|LText|LProjection|null; + + readonly data: ProjectionState; + + /** Projections can be added to elements or views. */ + readonly parent: LElement|LView; +} + +/** + * NOTES: + * + * Each Array costs 70 bytes and is composed of `Array` and `(array)` object + * - `Array` javascript visible object: 32 bytes + * - `(array)` VM object where the array is actually stored in: 38 bytes + * + * Each Object cost is 24 bytes plus 8 bytes per property. + * + * For small arrays, it is more efficient to store the data as a linked list + * of items rather than small arrays. However, the array access is faster as + * shown here: https://jsperf.com/small-arrays-vs-linked-objects + */ + +export interface LNodeInjector { + /** + * We need to store a reference to the injector's parent so DI can keep looking up + * the injector tree until it finds the dependency it's looking for. + */ + readonly parent: LNodeInjector|null; + + /** + * Allows access to the directives array in that node's static data and to + * the node's flags (for starting directive index and directive size). Necessary + * for DI to retrieve a directive from the data array if injector indicates + * it is there. + */ + readonly node: LElement|LContainer; + + /** + * The following bloom filter determines whether a directive is available + * on the associated node or not. This prevents us from searching the directives + * array at this level unless it's probable the directive is in it. + * + * - bf0: Check directive IDs 0-31 (IDs are % 128) + * - bf1: Check directive IDs 33-63 + * - bf2: Check directive IDs 64-95 + * - bf3: Check directive IDs 96-127 + * + * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters. + */ + bf0: number; + bf1: number; + bf2: number; + bf3: number; + + /** + * cbf0 - cbf3 properties determine whether a directive is available through a + * parent injector. They refer to the merged values of parent bloom filters. This + * allows us to skip looking up the chain unless it's probable that directive exists + * up the chain. + */ + cbf0: number; + cbf1: number; + cbf2: number; + cbf3: number; + injector: Injector|null; + + /** Stores the TemplateRef so subsequent injections of the TemplateRef get the same instance. */ + templateRef: TemplateRef|null; + + /** Stores the ViewContainerRef so subsequent injections of the ViewContainerRef get the same + * instance. */ + viewContainerRef: ViewContainerRef|null; + + /** Stores the ElementRef so subsequent injections of the ElementRef get the same instance. */ + elementRef: ElementRef|null; +} /** * `ViewState` stores all of the information needed to process the instructions as diff --git a/packages/core/src/render3/l_node.ts b/packages/core/src/render3/l_node.ts deleted file mode 100644 index 2cf337ba94..0000000000 --- a/packages/core/src/render3/l_node.ts +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {ElementRef, Injector, TemplateRef, ViewContainerRef} from '../core'; - -import {ContainerState, ProjectionState, QueryState, ViewState} from './interfaces'; -import {LNodeStatic} from './l_node_static'; -import {RComment, RElement, RText} from './renderer'; - - -/** - * LNodeFlags corresponds to the LNode.flags property. It contains information - * on how to map a particular set of bits in LNode.flags to the node type, directive - * count, or directive starting index. - * - * For example, if you wanted to check the type of a certain node, you would mask - * node.flags with TYPE_MASK and compare it to the value for a certain node type. e.g: - * - *```ts - * if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) {...} - *``` - */ -export const enum LNodeFlags { - Container = 0b00, - Projection = 0b01, - View = 0b10, - Element = 0b11, - ViewOrElement = 0b10, - SIZE_SKIP = 0b100, - SIZE_SHIFT = 2, - INDX_SHIFT = 12, - TYPE_MASK = 0b00000000000000000000000000000011, - SIZE_MASK = 0b00000000000000000000111111111100, - INDX_MASK = 0b11111111111111111111000000000000 -} - -/** - * LNode is an internal data structure which is used for the incremental DOM algorithm. - * The "L" stands for "Logical" to differentiate between `RNodes` (actual rendered DOM - * node) and our logical representation of DOM nodes, `LNodes`. - * - * The data structure is optimized for speed and size. - * - * In order to be fast, all subtypes of `LNode` should have the same shape. - * Because size of the `LNode` matters, many fields have multiple roles depending - * on the `LNode` subtype. - * - * See: https://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching - * - * NOTE: This is a private data structure and should not be exported by any of the - * instructions. - */ -export interface LNode { - /** - * This number stores three values using its bits: - * - * - the type of the node (first 2 bits) - * - the number of directives on that node (next 10 bits) - * - the starting index of the node's directives in the directives array (last 20 bits). - * - * The latter two values are necessary so DI can effectively search the directives associated - * with a node without searching the whole directives array. - */ - flags: LNodeFlags; - - /** - * The associated DOM node. Storing this allows us to: - * - append children to their element parents in the DOM (e.g. `parent.native.appendChild(...)`) - * - retrieve the sibling elements of text nodes whose creation / insertion has been delayed - * - mark locations where child views should be inserted (for containers) - */ - readonly native: RElement|RText|RComment|null; - - /** - * We need a reference to a node's parent so we can append the node to its parent's native - * element at the appropriate time. - */ - readonly parent: LNode|null; - - /** - * First child of the current node. - */ - child: LNode|null; - - /** - * The next sibling node. Necessary so we can propagate through the root nodes of a view - * to insert them or remove them from the DOM. - */ - next: LNode|null; - - /** - * If regular LElement, then `data` will be null. - * If LElement with component, then `data` contains ViewState. - * If LView, then `data` contains the ViewState. - * If LContainer, then `data` contains ContainerState. - * If LProjection, then `data` contains ProjectionState. - */ - readonly data: ViewState|ContainerState|ProjectionState|null; - - - /** - * Each node belongs to a view. - * - * When the injector is walking up a tree, it needs access to the `directives` (part of view). - */ - readonly view: ViewState; - - /** The injector associated with this node. Necessary for DI. */ - nodeInjector: LNodeInjector|null; - - /** - * Optional `QueryState` used for tracking queries. - * - * If present the node creation/updates are reported to the `QueryState`. - */ - query: QueryState|null; - - /** - * Pointer to the corresponding LNodeStatic object, which stores static - * data about this node. - */ - staticData: LNodeStatic|null; -} - - -/** LNode representing an element. */ -export interface LElement extends LNode { - /** The DOM element associated with this node. */ - readonly native: RElement; - - child: LContainer|LElement|LText|LProjection|null; - next: LContainer|LElement|LText|LProjection|null; - - /** If Component than data has ViewState (light DOM) */ - readonly data: ViewState|null; - - /** LElement nodes can be inside other LElement nodes or inside LViews. */ - readonly parent: LElement|LView; -} - -/** LNode representing a #text node. */ -export interface LText extends LNode { - /** The text node associated with this node. */ - native: RText; - child: null; - next: LContainer|LElement|LText|LProjection|null; - - /** LText nodes can be inside LElement nodes or inside LViews. */ - readonly parent: LElement|LView; - readonly data: null; -} - -/** - * Abstract node which contains root nodes of a view. - */ -export interface LView extends LNode { - readonly native: null; - child: LContainer|LElement|LText|LProjection|null; - next: LView|null; - - /** LView nodes can only be added to LContainers. */ - readonly parent: LContainer|null; - readonly data: ViewState; -} - -/** - * Abstract node container which contains other views. - */ -export interface LContainer extends LNode { - /** - * This comment node is appended to the container's parent element to mark where - * in the DOM the container's child views should be added. - * - * If the container is a root node of a view, this comment will not be appended - * until the parent view is processed. - */ - readonly native: RComment; - readonly data: ContainerState; - child: null; - next: LContainer|LElement|LText|LProjection|null; - - /** Containers can be added to elements or views. */ - readonly parent: LElement|LView|null; -} - - -export interface LProjection extends LNode { - readonly native: null; - child: null; - next: LContainer|LElement|LText|LProjection|null; - - readonly data: ProjectionState; - - /** Projections can be added to elements or views. */ - readonly parent: LElement|LView; -} - -/** - * NOTES: - * - * Each Array costs 70 bytes and is composed of `Array` and `(array)` object - * - `Array` javascript visible object: 32 bytes - * - `(array)` VM object where the array is actually stored in: 38 bytes - * - * Each Object cost is 24 bytes plus 8 bytes per property. - * - * For small arrays, it is more efficient to store the data as a linked list - * of items rather than small arrays. However, the array access is faster as - * shown here: https://jsperf.com/small-arrays-vs-linked-objects - */ - -export interface LNodeInjector { - /** - * We need to store a reference to the injector's parent so DI can keep looking up - * the injector tree until it finds the dependency it's looking for. - */ - readonly parent: LNodeInjector|null; - - /** - * Allows access to the directives array in that node's static data and to - * the node's flags (for starting directive index and directive size). Necessary - * for DI to retrieve a directive from the data array if injector indicates - * it is there. - */ - readonly node: LElement|LContainer; - - /** - * The following bloom filter determines whether a directive is available - * on the associated node or not. This prevents us from searching the directives - * array at this level unless it's probable the directive is in it. - * - * - bf0: Check directive IDs 0-31 (IDs are % 128) - * - bf1: Check directive IDs 33-63 - * - bf2: Check directive IDs 64-95 - * - bf3: Check directive IDs 96-127 - * - * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters. - */ - bf0: number; - bf1: number; - bf2: number; - bf3: number; - - /** - * cbf0 - cbf3 properties determine whether a directive is available through a - * parent injector. They refer to the merged values of parent bloom filters. This - * allows us to skip looking up the chain unless it's probable that directive exists - * up the chain. - */ - cbf0: number; - cbf1: number; - cbf2: number; - cbf3: number; - injector: Injector|null; - - /** Stores the TemplateRef so subsequent injections of the TemplateRef get the same instance. */ - templateRef: TemplateRef|null; - - /** Stores the ViewContainerRef so subsequent injections of the ViewContainerRef get the same - * instance. */ - viewContainerRef: ViewContainerRef|null; - - /** Stores the ElementRef so subsequent injections of the ElementRef get the same instance. */ - elementRef: ElementRef|null; -} diff --git a/packages/core/src/render3/l_node_static.ts b/packages/core/src/render3/l_node_static.ts index 186881d698..c47c691da3 100644 --- a/packages/core/src/render3/l_node_static.ts +++ b/packages/core/src/render3/l_node_static.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {DirectiveDef} from './public_interfaces'; +import {DirectiveDef} from './definition_interfaces'; /** The type of the global ngStaticData array. */ export type NgStaticData = (LNodeStatic | DirectiveDef| null)[]; diff --git a/packages/core/src/render3/node_assert.ts b/packages/core/src/render3/node_assert.ts index f9a69abec4..c998b65c3d 100644 --- a/packages/core/src/render3/node_assert.ts +++ b/packages/core/src/render3/node_assert.ts @@ -7,7 +7,7 @@ */ import {assertEqual, assertNotEqual} from './assert'; -import {LNode, LNodeFlags} from './l_node'; +import {LNode, LNodeFlags} from './interfaces'; export function assertNodeType(node: LNode, type: LNodeFlags) { assertNotEqual(node, null, 'node'); diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts index c239b9135c..f3ae3cec80 100644 --- a/packages/core/src/render3/node_manipulation.ts +++ b/packages/core/src/render3/node_manipulation.ts @@ -7,12 +7,12 @@ */ import {assertNotNull} from './assert'; -import {ContainerState, ProjectionState, ViewOrContainerState, ViewState} from './interfaces'; -import {LContainer, LElement, LNode, LNodeFlags, LProjection, LText, LView} from './l_node'; +import {ContainerState, LContainer, LElement, LNode, LNodeFlags, LProjection, LText, LView, ProjectionState, ViewOrContainerState, ViewState} from './interfaces'; import {assertNodeType} from './node_assert'; import {ProceduralRenderer3, RComment, RElement, RNode, RText} from './renderer'; + /** * Finds the closest DOM node above a given container in the hierarchy. * @@ -56,8 +56,7 @@ export function findNativeParent(containerNode: LContainer): RNode|null { * @param native Comment anchor for container * @returns The DOM element for which the view should insert elements */ -export function findBeforeNode(index: number, state: ContainerState, native: RComment): RElement| - RText|RComment { +function findBeforeNode(index: number, state: ContainerState, native: RNode): RNode { const views = state.views; // Find the node to insert in front of return index + 1 < views.length ? diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts index 71d6c8fca0..28aca44d8e 100644 --- a/packages/core/src/render3/query.ts +++ b/packages/core/src/render3/query.ts @@ -6,18 +6,21 @@ * found in the LICENSE file at https://angular.io/license */ -// We are temporarily importing the existing viewEngine from core so we can be sure we are +// We are temporarily importing the existing viewEngine_from core so we can be sure we are // correctly implementing its interfaces for backwards compatibility. import {Observable} from 'rxjs/Observable'; -import * as viewEngine from '../core'; +import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref'; +import {QueryList as viewEngine_QueryList} from '../linker/query_list'; +import {TemplateRef as viewEngine_TemplateRef} from '../linker/template_ref'; +import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_container_ref'; +import {Type} from '../type'; import {assertNotNull} from './assert'; +import {DirectiveDef} from './definition_interfaces'; import {getOrCreateContainerRef, getOrCreateElementRef, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from './di'; -import {QueryReadType, QueryState} from './interfaces'; -import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LView} from './l_node'; +import {LContainer, LElement, LNode, LNodeFlags, LNodeInjector, LView, QueryReadType, QueryState} from './interfaces'; import {assertNodeOfPossibleTypes} from './node_assert'; -import {DirectiveDef} from './public_interfaces'; @@ -38,7 +41,7 @@ export interface QueryPredicate { /** * If looking for directives than it contains the directive type. */ - type: viewEngine.Type|null; + type: Type|null; /** * If selector then contains local names to query for. @@ -65,7 +68,7 @@ export class QueryState_ implements QueryState { constructor(deep?: QueryPredicate) { this.deep = deep == null ? null : deep; } track( - queryList: viewEngine.QueryList, predicate: viewEngine.Type|string[], descend?: boolean, + queryList: viewEngine_QueryList, predicate: Type|string[], descend?: boolean, read?: QueryReadType): void { // TODO(misko): This is not right. In case of inherited state, a calling track will incorrectly // mutate parent. @@ -106,8 +109,8 @@ export class QueryState_ implements QueryState { } } -function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode): - viewEngine.ElementRef|viewEngine.TemplateRef|undefined { +function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode): viewEngine_ElementRef| + viewEngine_TemplateRef|undefined { ngDevMode && assertNodeOfPossibleTypes(node, LNodeFlags.Container, LNodeFlags.Element); if ((node.flags & LNodeFlags.TYPE_MASK) === LNodeFlags.Element) { return getOrCreateElementRef(nodeInjector); @@ -117,7 +120,7 @@ function readDefaultInjectable(nodeInjector: LNodeInjector, node: LNode): } function readFromNodeInjector(nodeInjector: LNodeInjector, node: LNode, read: QueryReadType | null): - viewEngine.ElementRef|viewEngine.ViewContainerRef|viewEngine.TemplateRef|undefined { + viewEngine_ElementRef|viewEngine_ViewContainerRef|viewEngine_TemplateRef|undefined { if (read === null) { return readDefaultInjectable(nodeInjector, node); } else if (read === QueryReadType.ElementRef) { @@ -166,8 +169,8 @@ function add(predicate: QueryPredicate| null, node: LNode) { } function createPredicate( - previous: QueryPredicate| null, queryList: QueryList, - predicate: viewEngine.Type| string[], read: QueryReadType | null): QueryPredicate { + previous: QueryPredicate| null, queryList: QueryList, predicate: Type| string[], + read: QueryReadType | null): QueryPredicate { const isArray = Array.isArray(predicate); const values = []; if ((queryList as any as QueryList_)._valuesTree === null) { @@ -176,14 +179,14 @@ function createPredicate( return { next: previous, list: queryList, - type: isArray ? null : predicate as viewEngine.Type, + type: isArray ? null : predicate as Type, selector: isArray ? predicate as string[] : null, read: read, values: values }; } -class QueryList_/* implements viewEngine.QueryList */ { +class QueryList_/* implements viewEngine_QueryList */ { dirty: boolean = false; changes: Observable; @@ -250,8 +253,8 @@ class QueryList_/* implements viewEngine.QueryList */ { // NOTE: this hack is here because IQueryList has private members and therefore // it can't be implemented only extended. -export type QueryList = viewEngine.QueryList; -export const QueryList: typeof viewEngine.QueryList = QueryList_ as any; +export type QueryList = viewEngine_QueryList; +export const QueryList: typeof viewEngine_QueryList = QueryList_ as any; export function queryRefresh(query: QueryList): boolean { return (query as any as QueryList_)._refresh(); diff --git a/packages/core/src/render3/renderer.ts b/packages/core/src/render3/renderer.ts index afa9ad185d..c2ea24a221 100644 --- a/packages/core/src/render3/renderer.ts +++ b/packages/core/src/render3/renderer.ts @@ -15,8 +15,9 @@ * it will be easy to implement such API. */ -import {RendererStyleFlags2, RendererType2, ViewEncapsulation} from '../core'; -import {ComponentDef} from './public_interfaces'; +import {ViewEncapsulation} from '../metadata/view'; +import {RendererStyleFlags2, RendererType2} from '../render/api'; + // TODO: cleanup once the code is merged in angular/angular export enum RendererStyleFlags3 { diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts index 61c41c7f52..54c567e0a1 100644 --- a/packages/core/test/render3/di_spec.ts +++ b/packages/core/test/render3/di_spec.ts @@ -11,7 +11,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core'; import {bloomAdd, bloomFindPossibleInjector} from '../../src/render3/di'; import {C, D, E, PublicFeature, T, V, b, b2, c, cR, cr, defineDirective, e, inject, injectElementRef, injectTemplateRef, injectViewContainerRef, t, v} from '../../src/render3/index'; import {createLNode, createViewState, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions'; -import {LNodeFlags, LNodeInjector} from '../../src/render3/l_node'; +import {LNodeFlags, LNodeInjector} from '../../src/render3/interfaces'; import {renderToHtml} from './render_util'; diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 573eee1735..3dc4a8e652 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -8,7 +8,7 @@ import {ComponentTemplate, ComponentType, PublicFeature, defineComponent, renderComponent as _renderComponent} from '../../src/render3/index'; import {NG_HOST_SYMBOL, createLNode, createViewState, renderTemplate} from '../../src/render3/instructions'; -import {LElement, LNodeFlags} from '../../src/render3/l_node'; +import {LElement, LNodeFlags} from '../../src/render3/interfaces'; import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/renderer'; import {getRendererFactory2} from './imported_renderer2';