From 5fa026fd81c6cb6996da448593a21b3f0a855c89 Mon Sep 17 00:00:00 2001 From: JoostK Date: Thu, 3 Dec 2020 23:03:23 +0100 Subject: [PATCH] refactor(compiler): add type information to `DefinitionMap` (#39961) This allows the code generation to correspond with a type, which is helpful for documentation and discoverability purposes. This does not offer any type-safety with respect to the actually generated code. PR Close #39961 --- packages/compiler/src/render3/partial/component.ts | 14 ++++++++------ packages/compiler/src/render3/partial/directive.ts | 10 ++++++---- packages/compiler/src/render3/view/util.ts | 11 ++++++++--- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/compiler/src/render3/partial/component.ts b/packages/compiler/src/render3/partial/component.ts index 050207051b..a19f0020bc 100644 --- a/packages/compiler/src/render3/partial/component.ts +++ b/packages/compiler/src/render3/partial/component.ts @@ -9,10 +9,11 @@ import * as core from '../../core'; import {DEFAULT_INTERPOLATION_CONFIG} from '../../ml_parser/interpolation_config'; import * as o from '../../output/output_ast'; import {Identifiers as R3} from '../r3_identifiers'; -import {R3ComponentDef, R3ComponentMetadata} from '../view/api'; +import {R3ComponentDef, R3ComponentMetadata, R3UsedDirectiveMetadata} from '../view/api'; import {createComponentType} from '../view/compiler'; import {ParsedTemplate} from '../view/template'; import {DefinitionMap} from '../view/util'; +import {R3DeclareComponentMetadata} from './api'; import {createDirectiveDefinitionMap} from './directive'; import {toOptionalLiteralArray} from './util'; @@ -34,9 +35,10 @@ export function compileDeclareComponentFromMetadata( /** * Gathers the declaration fields for a component into a `DefinitionMap`. */ -export function createComponentDefinitionMap( - meta: R3ComponentMetadata, template: ParsedTemplate): DefinitionMap { - const definitionMap = createDirectiveDefinitionMap(meta); +export function createComponentDefinitionMap(meta: R3ComponentMetadata, template: ParsedTemplate): + DefinitionMap { + const definitionMap: DefinitionMap = + createDirectiveDefinitionMap(meta); const templateMap = compileTemplateDefinition(template); @@ -76,7 +78,7 @@ export function createComponentDefinitionMap( * Compiles the provided template into its partial definition. */ function compileTemplateDefinition(template: ParsedTemplate): o.LiteralMapExpr { - const templateMap = new DefinitionMap(); + const templateMap = new DefinitionMap(); const templateExpr = typeof template.template === 'string' ? o.literal(template.template) : template.template; templateMap.set('source', templateExpr); @@ -94,7 +96,7 @@ function compileUsedDirectiveMetadata(meta: R3ComponentMetadata): o.LiteralArray (expr: o.Expression) => expr; return toOptionalLiteralArray(meta.directives, directive => { - const dirMeta = new DefinitionMap(); + const dirMeta = new DefinitionMap(); dirMeta.set('type', wrapType(directive.type)); dirMeta.set('selector', o.literal(directive.selector)); dirMeta.set('inputs', toOptionalLiteralArray(directive.inputs, o.literal)); diff --git a/packages/compiler/src/render3/partial/directive.ts b/packages/compiler/src/render3/partial/directive.ts index 368c8c1c67..c4d6cd0af3 100644 --- a/packages/compiler/src/render3/partial/directive.ts +++ b/packages/compiler/src/render3/partial/directive.ts @@ -10,6 +10,7 @@ import {Identifiers as R3} from '../r3_identifiers'; import {R3DirectiveDef, R3DirectiveMetadata, R3HostMetadata, R3QueryMetadata} from '../view/api'; import {createDirectiveType} from '../view/compiler'; import {asLiteral, conditionallyCreateMapObjectLiteral, DefinitionMap} from '../view/util'; +import {R3DeclareDirectiveMetadata, R3DeclareQueryMetadata} from './api'; import {toOptionalLiteralMap} from './util'; @@ -29,8 +30,9 @@ export function compileDeclareDirectiveFromMetadata(meta: R3DirectiveMetadata): * Gathers the declaration fields for a directive into a `DefinitionMap`. This allows for reusing * this logic for components, as they extend the directive metadata. */ -export function createDirectiveDefinitionMap(meta: R3DirectiveMetadata): DefinitionMap { - const definitionMap = new DefinitionMap(); +export function createDirectiveDefinitionMap(meta: R3DirectiveMetadata): + DefinitionMap { + const definitionMap = new DefinitionMap(); definitionMap.set('version', o.literal('0.0.0-PLACEHOLDER')); @@ -77,7 +79,7 @@ export function createDirectiveDefinitionMap(meta: R3DirectiveMetadata): Definit * by `R3DeclareQueryMetadata`. */ function compileQuery(query: R3QueryMetadata): o.LiteralMapExpr { - const meta = new DefinitionMap(); + const meta = new DefinitionMap(); meta.set('propertyName', o.literal(query.propertyName)); if (query.first) { meta.set('first', o.literal(true)); @@ -99,7 +101,7 @@ function compileQuery(query: R3QueryMetadata): o.LiteralMapExpr { * in `R3DeclareDirectiveMetadata['host']` */ function compileHostMetadata(meta: R3HostMetadata): o.LiteralMapExpr|null { - const hostMetadata = new DefinitionMap(); + const hostMetadata = new DefinitionMap>(); hostMetadata.set('attributes', toOptionalLiteralMap(meta.attributes, expression => expression)); hostMetadata.set('listeners', toOptionalLiteralMap(meta.listeners, o.literal)); hostMetadata.set('properties', toOptionalLiteralMap(meta.properties, o.literal)); diff --git a/packages/compiler/src/render3/view/util.ts b/packages/compiler/src/render3/view/util.ts index ae69c865ba..34e4fedd70 100644 --- a/packages/compiler/src/render3/view/util.ts +++ b/packages/compiler/src/render3/view/util.ts @@ -142,12 +142,17 @@ export function getQueryPredicate( } } -export class DefinitionMap { +/** + * A representation for an object literal used during codegen of definition objects. The generic + * type `T` allows to reference a documented type of the generated structure, such that the + * property names that are set can be resolved to their documented declaration. + */ +export class DefinitionMap { values: {key: string, quoted: boolean, value: o.Expression}[] = []; - set(key: string, value: o.Expression|null): void { + set(key: keyof T, value: o.Expression|null): void { if (value) { - this.values.push({key, value, quoted: false}); + this.values.push({key: key as string, value, quoted: false}); } }