-
Notifications
You must be signed in to change notification settings - Fork 24.8k
/
r3_pipe_compiler.ts
120 lines (102 loc) 路 3.7 KB
/
r3_pipe_compiler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* @license
* Copyright Google Inc. 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 {CompilePipeMetadata, identifierName} from '../compile_metadata';
import {CompileReflector} from '../compile_reflector';
import {DefinitionKind} from '../constant_pool';
import * as o from '../output/output_ast';
import {OutputContext, error} from '../util';
import {R3DependencyMetadata, R3FactoryTarget, compileFactoryFromMetadata, dependenciesFromGlobalMetadata} from './r3_factory';
import {Identifiers as R3} from './r3_identifiers';
import {typeWithParameters} from './util';
export interface R3PipeMetadata {
/**
* Name of the pipe type.
*/
name: string;
/**
* An expression representing a reference to the pipe itself.
*/
type: o.Expression;
/**
* Number of generic type parameters of the type itself.
*/
typeArgumentCount: number;
/**
* Name of the pipe.
*/
pipeName: string;
/**
* Dependencies of the pipe's constructor.
*/
deps: R3DependencyMetadata[]|null;
/**
* Whether the pipe is marked as pure.
*/
pure: boolean;
}
export function compilePipeFromMetadata(metadata: R3PipeMetadata) {
const definitionMapValues: {key: string, quoted: boolean, value: o.Expression}[] = [];
// e.g. `name: 'myPipe'`
definitionMapValues.push({key: 'name', value: o.literal(metadata.pipeName), quoted: false});
// e.g. `type: MyPipe`
definitionMapValues.push({key: 'type', value: metadata.type, quoted: false});
// e.g. `pure: true`
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, [
typeWithParameters(metadata.type, metadata.typeArgumentCount),
new o.ExpressionType(new o.LiteralExpr(metadata.pipeName)),
]));
return {expression, type};
}
/**
* Write a pipe definition to the output context.
*/
export function compilePipeFromRender2(
outputCtx: OutputContext, pipe: CompilePipeMetadata, reflector: CompileReflector) {
const name = identifierName(pipe.type);
if (!name) {
return error(`Cannot resolve the name of ${pipe.type}`);
}
const metadata: R3PipeMetadata = {
name,
pipeName: pipe.name,
type: outputCtx.importExpr(pipe.type.reference),
typeArgumentCount: 0,
deps: dependenciesFromGlobalMetadata(pipe.type, outputCtx, reflector),
pure: pipe.pure,
};
const res = compilePipeFromMetadata(metadata);
const factoryRes = compileFactoryFromMetadata(
{...metadata, injectFn: R3.directiveInject, target: R3FactoryTarget.Pipe});
const definitionField = outputCtx.constantPool.propertyNameOf(DefinitionKind.Pipe);
const ngFactoryDefStatement = new o.ClassStmt(
/* name */ name,
/* parent */ null,
/* fields */
[new o.ClassField(
/* name */ 'ngFactoryDef',
/* type */ o.INFERRED_TYPE,
/* modifiers */[o.StmtModifier.Static],
/* initializer */ factoryRes.factory)],
/* getters */[],
/* constructorMethod */ new o.ClassMethod(null, [], []),
/* methods */[]);
const pipeDefStatement = new o.ClassStmt(
/* name */ name,
/* parent */ null,
/* fields */[new o.ClassField(
/* name */ definitionField,
/* type */ o.INFERRED_TYPE,
/* modifiers */[o.StmtModifier.Static],
/* initializer */ res.expression)],
/* getters */[],
/* constructorMethod */ new o.ClassMethod(null, [], []),
/* methods */[]);
outputCtx.statements.push(ngFactoryDefStatement, pipeDefStatement);
}