@@ -4,9 +4,10 @@ import {Type, isBlank, isPresent, BaseException, normalizeBlank, stringify} from
44import { Promise , PromiseWrapper } from 'angular2/src/facade/async' ;
55import { List , ListWrapper , Map , MapWrapper } from 'angular2/src/facade/collection' ;
66
7- import { DirectiveMetadataReader } from './directive_metadata_reader ' ;
8- import { Component , Directive } from '../annotations_impl/annotations' ;
7+ import { DirectiveResolver } from './directive_resolver ' ;
8+
99import { AppProtoView } from './view' ;
10+ import { ElementBinder } from './element_binder' ;
1011import { ProtoViewRef } from './view_ref' ;
1112import { DirectiveBinding } from './element_injector' ;
1213import { TemplateResolver } from './template_resolver' ;
@@ -47,7 +48,7 @@ export class CompilerCache {
4748 */
4849@Injectable ( )
4950export class Compiler {
50- _reader : DirectiveMetadataReader ;
51+ _reader : DirectiveResolver ;
5152 _compilerCache :CompilerCache ;
5253 _compiling :Map < Type , Promise > ;
5354 _templateResolver : TemplateResolver ;
@@ -57,7 +58,7 @@ export class Compiler {
5758 _render : renderApi . RenderCompiler ;
5859 _protoViewFactory :ProtoViewFactory ;
5960
60- constructor ( reader : DirectiveMetadataReader ,
61+ constructor ( reader : DirectiveResolver ,
6162 cache :CompilerCache ,
6263 templateResolver : TemplateResolver ,
6364 componentUrlMapper : ComponentUrlMapper ,
@@ -79,11 +80,11 @@ export class Compiler {
7980 if ( directiveTypeOrBinding instanceof DirectiveBinding ) {
8081 return directiveTypeOrBinding ;
8182 } else if ( directiveTypeOrBinding instanceof Binding ) {
82- let meta = this . _reader . read ( directiveTypeOrBinding . token ) ;
83- return DirectiveBinding . createFromBinding ( directiveTypeOrBinding , meta . annotation ) ;
83+ let annotation = this . _reader . resolve ( directiveTypeOrBinding . token ) ;
84+ return DirectiveBinding . createFromBinding ( directiveTypeOrBinding , annotation ) ;
8485 } else {
85- let meta = this . _reader . read ( directiveTypeOrBinding ) ;
86- return DirectiveBinding . createFromType ( meta . type , meta . annotation ) ;
86+ let annotation = this . _reader . resolve ( directiveTypeOrBinding ) ;
87+ return DirectiveBinding . createFromType ( directiveTypeOrBinding , annotation ) ;
8788 }
8889 }
8990
@@ -93,9 +94,9 @@ export class Compiler {
9394 var componentBinding = this . _bindDirective ( componentTypeOrBinding ) ;
9495 this . _assertTypeIsComponent ( componentBinding ) ;
9596
96- var directiveMetadata = Compiler . buildRenderDirective ( componentBinding ) ;
97+ var directiveMetadata = componentBinding . metadata ;
9798 return this . _render . compileHost ( directiveMetadata ) . then ( ( hostRenderPv ) => {
98- return this . _compileNestedProtoViews ( null , null , hostRenderPv , [ componentBinding ] , true ) ;
99+ return this . _compileNestedProtoViews ( componentBinding , hostRenderPv , [ componentBinding ] ) ;
99100 } ) . then ( ( appProtoView ) => {
100101 return new ProtoViewRef ( appProtoView ) ;
101102 } ) ;
@@ -139,44 +140,39 @@ export class Compiler {
139140 ) ;
140141 var renderTemplate = this . _buildRenderTemplate ( component , template , directives ) ;
141142 pvPromise = this . _render . compile ( renderTemplate ) . then ( ( renderPv ) => {
142- return this . _compileNestedProtoViews ( null , componentBinding , renderPv , directives , true ) ;
143+ return this . _compileNestedProtoViews ( componentBinding , renderPv , directives ) ;
143144 } ) ;
144145
145146 MapWrapper . set ( this . _compiling , component , pvPromise ) ;
146147 return pvPromise ;
147148 }
148149
149150 // TODO(tbosch): union type return AppProtoView or Promise<AppProtoView>
150- _compileNestedProtoViews ( parentProtoView , componentBinding , renderPv , directives , isComponentRootView ) {
151- var nestedPVPromises = [ ] ;
152- var protoView = this . _protoViewFactory . createProtoView ( parentProtoView , componentBinding , renderPv , directives ) ;
153- if ( isComponentRootView && isPresent ( componentBinding ) ) {
151+ _compileNestedProtoViews ( componentBinding , renderPv , directives ) {
152+ var protoViews = this . _protoViewFactory . createAppProtoViews ( componentBinding , renderPv , directives ) ;
153+ var protoView = protoViews [ 0 ] ;
154+ // TODO(tbosch): we should be caching host protoViews as well!
155+ // -> need a separate cache for this...
156+ if ( renderPv . type === renderApi . ProtoViewDto . COMPONENT_VIEW_TYPE && isPresent ( componentBinding ) ) {
154157 // Populate the cache before compiling the nested components,
155158 // so that components can reference themselves in their template.
156159 var component = componentBinding . key . token ;
157160 this . _compilerCache . set ( component , protoView ) ;
158161 MapWrapper . delete ( this . _compiling , component ) ;
159162 }
160163
161- var binderIndex = 0 ;
162- ListWrapper . forEach ( protoView . elementBinders , ( elementBinder ) => {
164+ var nestedPVPromises = [ ] ;
165+ ListWrapper . forEach ( this . _collectComponentElementBinders ( protoViews ) , ( elementBinder ) => {
163166 var nestedComponent = elementBinder . componentDirective ;
164- var nestedRenderProtoView = renderPv . elementBinders [ binderIndex ] . nestedProtoView ;
165167 var elementBinderDone = ( nestedPv ) => {
166168 elementBinder . nestedProtoView = nestedPv ;
167169 } ;
168- var nestedCall = null ;
169- if ( isPresent ( nestedComponent ) ) {
170- nestedCall = this . _compile ( nestedComponent ) ;
171- } else if ( isPresent ( nestedRenderProtoView ) ) {
172- nestedCall = this . _compileNestedProtoViews ( protoView , componentBinding , nestedRenderProtoView , directives , false ) ;
173- }
170+ var nestedCall = this . _compile ( nestedComponent ) ;
174171 if ( PromiseWrapper . isPromise ( nestedCall ) ) {
175172 ListWrapper . push ( nestedPVPromises , nestedCall . then ( elementBinderDone ) ) ;
176173 } else if ( isPresent ( nestedCall ) ) {
177174 elementBinderDone ( nestedCall ) ;
178175 }
179- binderIndex ++ ;
180176 } ) ;
181177
182178 var protoViewDone = ( _ ) => {
@@ -189,6 +185,18 @@ export class Compiler {
189185 }
190186 }
191187
188+ _collectComponentElementBinders ( protoViews :List < AppProtoView > ) :List < ElementBinder > {
189+ var componentElementBinders = [ ] ;
190+ ListWrapper . forEach ( protoViews , ( protoView ) => {
191+ ListWrapper . forEach ( protoView . elementBinders , ( elementBinder ) => {
192+ if ( isPresent ( elementBinder . componentDirective ) ) {
193+ ListWrapper . push ( componentElementBinders , elementBinder ) ;
194+ }
195+ } ) ;
196+ } ) ;
197+ return componentElementBinders ;
198+ }
199+
192200 _buildRenderTemplate ( component , view , directives ) : renderApi . ViewDefinition {
193201 var componentUrl = this . _urlResolver . resolve (
194202 this . _appUrl , this . _componentUrlMapper . getUrl ( component )
@@ -206,36 +214,7 @@ export class Compiler {
206214 componentId : stringify ( component ) ,
207215 absUrl : templateAbsUrl ,
208216 template : view . template ,
209- directives : ListWrapper . map ( directives , Compiler . buildRenderDirective )
210- } ) ;
211- }
212-
213- static buildRenderDirective ( directiveBinding ) :renderApi . DirectiveMetadata {
214- var ann = directiveBinding . annotation ;
215- var renderType ;
216- var compileChildren = ann . compileChildren ;
217- if ( ann instanceof Component ) {
218- renderType = renderApi . DirectiveMetadata . COMPONENT_TYPE ;
219- } else {
220- renderType = renderApi . DirectiveMetadata . DIRECTIVE_TYPE ;
221- }
222- var readAttributes = [ ] ;
223- ListWrapper . forEach ( directiveBinding . dependencies , ( dep ) => {
224- if ( isPresent ( dep . attributeName ) ) {
225- ListWrapper . push ( readAttributes , dep . attributeName ) ;
226- }
227- } ) ;
228- return new renderApi . DirectiveMetadata ( {
229- id : stringify ( directiveBinding . key . token ) ,
230- type : renderType ,
231- selector : ann . selector ,
232- compileChildren : compileChildren ,
233- hostListeners : isPresent ( ann . hostListeners ) ? MapWrapper . createFromStringMap ( ann . hostListeners ) : null ,
234- hostProperties : isPresent ( ann . hostProperties ) ? MapWrapper . createFromStringMap ( ann . hostProperties ) : null ,
235- hostAttributes : isPresent ( ann . hostAttributes ) ? MapWrapper . createFromStringMap ( ann . hostAttributes ) : null ,
236- hostActions : isPresent ( ann . hostActions ) ? MapWrapper . createFromStringMap ( ann . hostActions ) : null ,
237- properties : isPresent ( ann . properties ) ? MapWrapper . createFromStringMap ( ann . properties ) : null ,
238- readAttributes : readAttributes
217+ directives : ListWrapper . map ( directives , directiveBinding => directiveBinding . metadata )
239218 } ) ;
240219 }
241220
@@ -260,7 +239,7 @@ export class Compiler {
260239 }
261240
262241 _assertTypeIsComponent ( directiveBinding :DirectiveBinding ) :void {
263- if ( ! ( directiveBinding . annotation instanceof Component ) ) {
242+ if ( directiveBinding . metadata . type !== renderApi . DirectiveMetadata . COMPONENT_TYPE ) {
264243 throw new BaseException ( `Could not load '${ stringify ( directiveBinding . key . token ) } ' because it is not a component.` ) ;
265244 }
266245 }
0 commit comments