refactor(compiler-cli): implement ɵɵngDeclarePipe() (#40803)
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial compilation, and processing of those calls in the linker and JIT compiler. See #40677 PR Close #40803
This commit is contained in:
committed by
Joey Perrott
parent
6425a6d543
commit
9cb43fb507
@@ -105,6 +105,7 @@ export {R3Reference, devOnlyGuardedExpression, getSafePropertyAccessString} from
|
||||
export {compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings, ParsedHostBindings, verifyHostBindings} from './render3/view/compiler';
|
||||
export {compileDeclareComponentFromMetadata} from './render3/partial/component';
|
||||
export {compileDeclareDirectiveFromMetadata} from './render3/partial/directive';
|
||||
export {compileDeclarePipeFromMetadata} from './render3/partial/pipe';
|
||||
export {publishFacade} from './jit_compiler_facade';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ export interface ExportedCompilerFacade {
|
||||
export interface CompilerFacade {
|
||||
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):
|
||||
any;
|
||||
compilePipeDeclaration(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, declaration: R3DeclarePipeFacade): any;
|
||||
compileInjectable(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;
|
||||
compileInjector(
|
||||
@@ -255,6 +257,12 @@ export interface R3DeclareQueryMetadataFacade {
|
||||
emitDistinctChangesOnly?: boolean;
|
||||
}
|
||||
|
||||
export interface R3DeclarePipeFacade {
|
||||
type: Function;
|
||||
name: string;
|
||||
pure?: boolean;
|
||||
}
|
||||
|
||||
export interface ParseSourceSpan {
|
||||
start: any;
|
||||
end: any;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
|
||||
import {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, OpaqueValue, R3ComponentMetadataFacade, R3DeclareComponentFacade, R3DeclareDirectiveFacade, R3DeclareQueryMetadataFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3FactoryDefMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
|
||||
import {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, OpaqueValue, R3ComponentMetadataFacade, R3DeclareComponentFacade, R3DeclareDirectiveFacade, R3DeclarePipeFacade, R3DeclareQueryMetadataFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3FactoryDefMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
|
||||
import {ConstantPool} from './constant_pool';
|
||||
import {ChangeDetectionStrategy, HostBinding, HostListener, Input, Output, Type, ViewEncapsulation} from './core';
|
||||
import {Identifiers} from './identifiers';
|
||||
@@ -50,6 +50,13 @@ export class CompilerFacadeImpl implements CompilerFacade {
|
||||
return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
|
||||
}
|
||||
|
||||
compilePipeDeclaration(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
declaration: R3DeclarePipeFacade): any {
|
||||
const meta = convertDeclarePipeFacadeToMetadata(declaration);
|
||||
return compilePipeFromMetadata(meta);
|
||||
}
|
||||
|
||||
compileInjectable(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3InjectableMetadataFacade): any {
|
||||
@@ -513,6 +520,19 @@ function parseInputOutputs(values: string[]): StringMap {
|
||||
}, {} as StringMap);
|
||||
}
|
||||
|
||||
function convertDeclarePipeFacadeToMetadata(declaration: R3DeclarePipeFacade): R3PipeMetadata {
|
||||
return {
|
||||
name: declaration.type.name,
|
||||
type: wrapReference(declaration.type),
|
||||
internalType: new WrappedNodeExpr(declaration.type),
|
||||
typeArgumentCount: 0,
|
||||
pipeName: declaration.name,
|
||||
deps: null,
|
||||
pure: declaration.pure ?? true,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export function publishFacade(global: any) {
|
||||
const ng: ExportedCompilerFacade = global.ng || (global.ng = {});
|
||||
ng.ɵcompilerFacade = new CompilerFacadeImpl();
|
||||
|
||||
@@ -23,10 +23,10 @@ export interface R3PartialDeclaration {
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface describes the shape of the object that partial directive declarations are compiled
|
||||
* into. This serves only as documentation, as conformance of this interface is not enforced during
|
||||
* the generation of the partial declaration, nor when the linker applies full compilation from the
|
||||
* partial declaration.
|
||||
* Describes the shape of the object that the `ɵɵngDeclareDirective() function accepts.
|
||||
*
|
||||
* This interface serves primarily as documentation, as conformance to this interface is not
|
||||
* enforced during linking.
|
||||
*/
|
||||
export interface R3DeclareDirectiveMetadata extends R3PartialDeclaration {
|
||||
/**
|
||||
@@ -114,8 +114,10 @@ export interface R3DeclareDirectiveMetadata extends R3PartialDeclaration {
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension of `R3DeclareDirectiveMetadata` that declares the shape of a partial declaration of
|
||||
* a component.
|
||||
* Describes the shape of the object that the `ɵɵngDeclareComponent()` function accepts.
|
||||
*
|
||||
* This interface serves primarily as documentation, as conformance to this interface is not
|
||||
* enforced during linking.
|
||||
*/
|
||||
export interface R3DeclareComponentMetadata extends R3DeclareDirectiveMetadata {
|
||||
/**
|
||||
@@ -261,3 +263,30 @@ export interface R3DeclareQueryMetadata {
|
||||
*/
|
||||
static?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the shape of the object that the `ɵɵngDeclarePipe()` function accepts.
|
||||
*
|
||||
* This interface serves primarily as documentation, as conformance to this interface is not
|
||||
* enforced during linking.
|
||||
*/
|
||||
export interface R3DeclarePipeMetadata extends R3PartialDeclaration {
|
||||
/**
|
||||
* Reference to the pipe class itself.
|
||||
*/
|
||||
type: o.Expression;
|
||||
|
||||
/**
|
||||
* The name to use in templates to refer to this pipe.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Whether this pipe is "pure".
|
||||
*
|
||||
* A pure pipe's `transform()` method is only invoked when its input arguments change.
|
||||
*
|
||||
* Default: true.
|
||||
*/
|
||||
pure?: boolean;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @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';
|
||||
import {Identifiers as R3} from '../r3_identifiers';
|
||||
import {createPipeType, R3PipeMetadata} from '../r3_pipe_compiler';
|
||||
import {R3PipeDef} from '../view/api';
|
||||
import {DefinitionMap} from '../view/util';
|
||||
import {R3DeclarePipeMetadata} from './api';
|
||||
|
||||
|
||||
/**
|
||||
* Compile a Pipe declaration defined by the `R3PipeMetadata`.
|
||||
*/
|
||||
export function compileDeclarePipeFromMetadata(meta: R3PipeMetadata): R3PipeDef {
|
||||
const definitionMap = createPipeDefinitionMap(meta);
|
||||
|
||||
const expression = o.importExpr(R3.declarePipe).callFn([definitionMap.toLiteralMap()]);
|
||||
const type = createPipeType(meta);
|
||||
|
||||
return {expression, type};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers the declaration fields for a Pipe into a `DefinitionMap`. This allows for reusing
|
||||
* this logic for components, as they extend the Pipe metadata.
|
||||
*/
|
||||
export function createPipeDefinitionMap(meta: R3PipeMetadata):
|
||||
DefinitionMap<R3DeclarePipeMetadata> {
|
||||
const definitionMap = new DefinitionMap<R3DeclarePipeMetadata>();
|
||||
|
||||
definitionMap.set('version', o.literal('0.0.0-PLACEHOLDER'));
|
||||
definitionMap.set('ngImport', o.importExpr(R3.core));
|
||||
|
||||
// e.g. `type: MyPipe`
|
||||
definitionMap.set('type', meta.internalType);
|
||||
// e.g. `name: "myPipe"`
|
||||
definitionMap.set('name', o.literal(meta.pipeName));
|
||||
|
||||
if (meta.pure === false) {
|
||||
// e.g. `pure: false`
|
||||
definitionMap.set('pure', o.literal(meta.pure));
|
||||
}
|
||||
|
||||
return definitionMap;
|
||||
}
|
||||
@@ -294,6 +294,7 @@ export class Identifiers {
|
||||
static PipeDefWithMeta: o.ExternalReference = {name: 'ɵɵPipeDefWithMeta', moduleName: CORE};
|
||||
|
||||
static definePipe: o.ExternalReference = {name: 'ɵɵdefinePipe', moduleName: CORE};
|
||||
static declarePipe: o.ExternalReference = {name: 'ɵɵngDeclarePipe', moduleName: CORE};
|
||||
|
||||
static queryRefresh: o.ExternalReference = {name: 'ɵɵqueryRefresh', moduleName: CORE};
|
||||
static viewQuery: o.ExternalReference = {name: 'ɵɵviewQuery', moduleName: CORE};
|
||||
|
||||
@@ -15,6 +15,7 @@ import {error, OutputContext} from '../util';
|
||||
import {compileFactoryFunction, dependenciesFromGlobalMetadata, R3DependencyMetadata, R3FactoryTarget} from './r3_factory';
|
||||
import {Identifiers as R3} from './r3_identifiers';
|
||||
import {R3Reference, typeWithParameters, wrapReference} from './util';
|
||||
import {R3PipeDef} from './view/api';
|
||||
|
||||
export interface R3PipeMetadata {
|
||||
/**
|
||||
@@ -57,7 +58,7 @@ export interface R3PipeMetadata {
|
||||
pure: boolean;
|
||||
}
|
||||
|
||||
export function compilePipeFromMetadata(metadata: R3PipeMetadata) {
|
||||
export function compilePipeFromMetadata(metadata: R3PipeMetadata): R3PipeDef {
|
||||
const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = [];
|
||||
|
||||
// e.g. `name: 'myPipe'`
|
||||
@@ -70,12 +71,16 @@ export function compilePipeFromMetadata(metadata: R3PipeMetadata) {
|
||||
definitionMapValues.push({key: 'pure', value: o.literal(metadata.pure), quoted: false});
|
||||
|
||||
const expression = o.importExpr(R3.definePipe).callFn([o.literalMap(definitionMapValues)]);
|
||||
const type = new o.ExpressionType(o.importExpr(R3.PipeDefWithMeta, [
|
||||
const type = createPipeType(metadata);
|
||||
|
||||
return {expression, type};
|
||||
}
|
||||
|
||||
export function createPipeType(metadata: R3PipeMetadata): o.Type {
|
||||
return new o.ExpressionType(o.importExpr(R3.PipeDefWithMeta, [
|
||||
typeWithParameters(metadata.type.type, metadata.typeArgumentCount),
|
||||
new o.ExpressionType(new o.LiteralExpr(metadata.pipeName)),
|
||||
]));
|
||||
|
||||
return {expression, type};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -349,6 +349,14 @@ export interface R3ComponentDef {
|
||||
type: o.Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output of render3 pipe compilation.
|
||||
*/
|
||||
export interface R3PipeDef {
|
||||
expression: o.Expression;
|
||||
type: o.Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mappings indicating how the class interacts with its
|
||||
* host element (host bindings, listeners, etc).
|
||||
|
||||
Reference in New Issue
Block a user