From 04bfe87764cc3de634ef6b3c07101fc4aa9cd6ae Mon Sep 17 00:00:00 2001 From: atscott Date: Wed, 2 Oct 2019 10:21:24 -0700 Subject: [PATCH] Revert "feat(core): default to dynamic queries (#32720)" (#32966) This reverts commit 948b01ce55c7874604016bda87187e8a713d8acc. PR Close #32966 --- .../src/view_compiler/view_compiler.ts | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/compiler/src/view_compiler/view_compiler.ts b/packages/compiler/src/view_compiler/view_compiler.ts index b3cfd9eff7..8310f7e104 100644 --- a/packages/compiler/src/view_compiler/view_compiler.ts +++ b/packages/compiler/src/view_compiler/view_compiler.ts @@ -37,6 +37,7 @@ export class ViewCompiler { outputCtx: OutputContext, component: CompileDirectiveMetadata, template: TemplateAst[], styles: o.Expression, usedPipes: CompilePipeSummary[]): ViewCompileResult { let embeddedViewCount = 0; + const staticQueryIds = findStaticQueryIds(template); let renderComponentVarName: string = undefined !; if (!component.isHost) { @@ -65,7 +66,7 @@ export class ViewCompiler { const embeddedViewIndex = embeddedViewCount++; return new ViewBuilder( this._reflector, outputCtx, parent, component, embeddedViewIndex, usedPipes, - viewBuilderFactory); + staticQueryIds, viewBuilderFactory); }; const visitor = viewBuilderFactory(null); @@ -115,6 +116,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { private reflector: CompileReflector, private outputCtx: OutputContext, private parent: ViewBuilder|null, private component: CompileDirectiveMetadata, private embeddedViewIndex: number, private usedPipes: CompilePipeSummary[], + private staticQueryIds: Map, private viewBuilderFactory: ViewBuilderFactory) { // TODO(tbosch): The old view compiler used to use an `any` type // for the context in any embedded view. We keep this behaivor for now @@ -137,11 +139,13 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { } if (!this.parent) { + const queryIds = staticViewQueryIds(this.staticQueryIds); this.component.viewQueries.forEach((query, queryIndex) => { // Note: queries start with id 1 so we can use the number in a Bloom filter! const queryId = queryIndex + 1; const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All; - const flags = NodeFlags.TypeViewQuery | calcStaticDynamicQueryFlags(query); + const flags = + NodeFlags.TypeViewQuery | calcStaticDynamicQueryFlags(queryIds, queryId, query); this.nodes.push(() => ({ sourceSpan: null, nodeFlags: flags, @@ -408,16 +412,19 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { const hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[] = []; this._visitComponentFactoryResolverProvider(ast.directives); - ast.providers.forEach(providerAst => { + ast.providers.forEach((providerAst, providerIndex) => { let dirAst: DirectiveAst = undefined !; - ast.directives.forEach(localDirAst => { + let dirIndex: number = undefined !; + ast.directives.forEach((localDirAst, i) => { if (localDirAst.directive.type.reference === tokenReference(providerAst.token)) { dirAst = localDirAst; + dirIndex = i; } }); if (dirAst) { - const {hostBindings: dirHostBindings, hostEvents: dirHostEvents} = - this._visitDirective(providerAst, dirAst, ast.references, ast.queryMatches, usedEvents); + const {hostBindings: dirHostBindings, hostEvents: dirHostEvents} = this._visitDirective( + providerAst, dirAst, dirIndex, nodeIndex, ast.references, ast.queryMatches, usedEvents, + this.staticQueryIds.get(ast) !); hostBindings.push(...dirHostBindings); hostEvents.push(...dirHostEvents); } else { @@ -472,8 +479,9 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { } private _visitDirective( - providerAst: ProviderAst, dirAst: DirectiveAst, refs: ReferenceAst[], - queryMatches: QueryMatch[], usedEvents: Map): { + providerAst: ProviderAst, dirAst: DirectiveAst, directiveIndex: number, + elementNodeIndex: number, refs: ReferenceAst[], queryMatches: QueryMatch[], + usedEvents: Map, queryIds: StaticAndDynamicQueryIds): { hostBindings: {context: o.Expression, inputAst: BoundElementPropertyAst, dirAst: DirectiveAst}[], hostEvents: {context: o.Expression, eventAst: BoundEventAst, dirAst: DirectiveAst}[] @@ -484,7 +492,8 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { dirAst.directive.queries.forEach((query, queryIndex) => { const queryId = dirAst.contentQueryStartId + queryIndex; - const flags = NodeFlags.TypeContentQuery | calcStaticDynamicQueryFlags(query); + const flags = + NodeFlags.TypeContentQuery | calcStaticDynamicQueryFlags(queryIds, queryId, query); const bindingType = query.first ? QueryBindingType.First : QueryBindingType.All; this.nodes.push(() => ({ sourceSpan: dirAst.sourceSpan, @@ -610,6 +619,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver { tokenExpr: o.Expression, sourceSpan: ParseSourceSpan }) { + const nodeIndex = this.nodes.length; // providerDef( // flags: NodeFlags, matchedQueries: [string, QueryValueType][], token:any, // value: any, deps: ([DepFlags, any] | any)[]): NodeDef; @@ -1076,11 +1086,12 @@ function elementEventNameAndTarget( } } -function calcStaticDynamicQueryFlags(query: CompileQueryMetadata) { +function calcStaticDynamicQueryFlags( + queryIds: StaticAndDynamicQueryIds, queryId: number, query: CompileQueryMetadata) { let flags = NodeFlags.None; - // Note: We only make queries static that query for a single item and the user specifically - // set the to be static. This is because of backwards compatibility with the old view compiler... - if (query.first && query.static) { + // Note: We only make queries static that query for a single item. + // This is because of backwards compatibility with the old view compiler... + if (query.first && shouldResolveAsStaticQuery(queryIds, queryId, query)) { flags |= NodeFlags.StaticQuery; } else { flags |= NodeFlags.DynamicQuery; @@ -1088,6 +1099,16 @@ function calcStaticDynamicQueryFlags(query: CompileQueryMetadata) { return flags; } +function shouldResolveAsStaticQuery( + queryIds: StaticAndDynamicQueryIds, queryId: number, query: CompileQueryMetadata): boolean { + // If query.static has been set by the user, use that value to determine whether + // the query is static. If none has been set, sort the query into static/dynamic + // based on query results (i.e. dynamic if CD needs to run to get all results). + return query.static || + query.static == null && + (queryIds.staticQueryIds.has(queryId) || !queryIds.dynamicQueryIds.has(queryId)); +} + export function elementEventFullName(target: string | null, name: string): string { return target ? `${target}:${name}` : name; }