diff --git a/packages/compiler/src/render3/partial/directive.ts b/packages/compiler/src/render3/partial/directive.ts index 71496c4225..06879c7608 100644 --- a/packages/compiler/src/render3/partial/directive.ts +++ b/packages/compiler/src/render3/partial/directive.ts @@ -8,8 +8,9 @@ import * as o from '../../output/output_ast'; import {Identifiers as R3} from '../r3_identifiers'; import {R3DirectiveDef, R3DirectiveMetadata, R3HostMetadata, R3QueryMetadata} from '../view/api'; -import {createDirectiveTypeParams} from '../view/compiler'; +import {createDirectiveType} from '../view/compiler'; import {asLiteral, conditionallyCreateMapObjectLiteral, DefinitionMap} from '../view/util'; +import {toOptionalLiteralMap} from './util'; /** @@ -19,9 +20,7 @@ export function compileDeclareDirectiveFromMetadata(meta: R3DirectiveMetadata): const definitionMap = createDirectiveDefinitionMap(meta); const expression = o.importExpr(R3.declareDirective).callFn([definitionMap.toLiteralMap()]); - - const typeParams = createDirectiveTypeParams(meta); - const type = o.expressionType(o.importExpr(R3.DirectiveDefWithMeta, typeParams)); + const type = createDirectiveType(meta); return {expression, type}; } @@ -118,26 +117,3 @@ function compileHostMetadata(meta: R3HostMetadata): o.LiteralMapExpr|null { return null; } } - -/** - * Creates an object literal expression from the given object, mapping all values to an expression - * using the provided mapping function. If the object has no keys, then null is returned. - * - * @param object The object to transfer into an object literal expression. - * @param mapper The logic to use for creating an expression for the object's values. - * @returns An object literal expression representing `object`, or null if `object` does not have - * any keys. - */ -function toOptionalLiteralMap( - object: {[key: string]: T}, mapper: (value: T) => o.Expression): o.LiteralMapExpr|null { - const entries = Object.keys(object).map(key => { - const value = object[key]; - return {key, value: mapper(value), quoted: true}; - }); - - if (entries.length > 0) { - return o.literalMap(entries); - } else { - return null; - } -} diff --git a/packages/compiler/src/render3/partial/util.ts b/packages/compiler/src/render3/partial/util.ts new file mode 100644 index 0000000000..c99168a979 --- /dev/null +++ b/packages/compiler/src/render3/partial/util.ts @@ -0,0 +1,48 @@ +/** + * @license + * Copyright Google LLC 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 * as o from '../../output/output_ast'; + +/** + * Creates an array literal expression from the given array, mapping all values to an expression + * using the provided mapping function. If the array is empty or null, then null is returned. + * + * @param values The array to transfer into literal array expression. + * @param mapper The logic to use for creating an expression for the array's values. + * @returns An array literal expression representing `values`, or null if `values` is empty or + * is itself null. + */ +export function toOptionalLiteralArray( + values: T[]|null, mapper: (value: T) => o.Expression): o.LiteralArrayExpr|null { + if (values === null || values.length === 0) { + return null; + } + return o.literalArr(values.map(value => mapper(value))); +} + +/** + * Creates an object literal expression from the given object, mapping all values to an expression + * using the provided mapping function. If the object has no keys, then null is returned. + * + * @param object The object to transfer into an object literal expression. + * @param mapper The logic to use for creating an expression for the object's values. + * @returns An object literal expression representing `object`, or null if `object` does not have + * any keys. + */ +export function toOptionalLiteralMap( + object: {[key: string]: T}, mapper: (value: T) => o.Expression): o.LiteralMapExpr|null { + const entries = Object.keys(object).map(key => { + const value = object[key]; + return {key, value: mapper(value), quoted: true}; + }); + + if (entries.length > 0) { + return o.literalMap(entries); + } else { + return null; + } +} diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts index cc72464a9d..c0a4ced776 100644 --- a/packages/compiler/src/render3/view/compiler.ts +++ b/packages/compiler/src/render3/view/compiler.ts @@ -22,7 +22,7 @@ import {CONTENT_ATTR, HOST_ATTR} from '../../style_compiler'; import {BindingParser} from '../../template_parser/binding_parser'; import {error, OutputContext} from '../../util'; import {BoundEvent} from '../r3_ast'; -import {compileFactoryFunction, R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType} from '../r3_factory'; +import {compileFactoryFunction, R3FactoryTarget} from '../r3_factory'; import {Identifiers as R3} from '../r3_identifiers'; import {Render3ParseResult} from '../r3_template_transform'; import {prepareSyntheticListenerFunctionName, prepareSyntheticPropertyName, typeWithParameters} from '../util'; @@ -123,9 +123,7 @@ export function compileDirectiveFromMetadata( const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser); addFeatures(definitionMap, meta); const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]); - - const typeParams = createDirectiveTypeParams(meta); - const type = o.expressionType(o.importExpr(R3.DirectiveDefWithMeta, typeParams)); + const type = createDirectiveType(meta); return {expression, type}; } @@ -264,15 +262,21 @@ export function compileComponentFromMetadata( } const expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]); - - - const typeParams = createDirectiveTypeParams(meta); - typeParams.push(stringArrayAsType(meta.template.ngContentSelectors)); - const type = o.expressionType(o.importExpr(R3.ComponentDefWithMeta, typeParams)); + const type = createComponentType(meta); return {expression, type}; } +/** + * Creates the type specification from the component meta. This type is inserted into .d.ts files + * to be consumed by upstream compilations. + */ +export function createComponentType(meta: R3ComponentMetadata): o.Type { + const typeParams = createDirectiveTypeParams(meta); + typeParams.push(stringArrayAsType(meta.template.ngContentSelectors)); + return o.expressionType(o.importExpr(R3.ComponentDefWithMeta, typeParams)); +} + /** * A wrapper around `compileDirective` which depends on render2 global analysis data as its input * instead of the `R3DirectiveMetadata`. @@ -507,6 +511,15 @@ export function createDirectiveTypeParams(meta: R3DirectiveMetadata): o.Type[] { ]; } +/** + * Creates the type specification from the directive meta. This type is inserted into .d.ts files + * to be consumed by upstream compilations. + */ +export function createDirectiveType(meta: R3DirectiveMetadata): o.Type { + const typeParams = createDirectiveTypeParams(meta); + return o.expressionType(o.importExpr(R3.DirectiveDefWithMeta, typeParams)); +} + // Define and update any view queries function createViewQueriesFunction( viewQueries: R3QueryMetadata[], constantPool: ConstantPool, name?: string): o.Expression {