refactor(compiler-cli): emit `forwardRef` invocation for forward type references (#40117)
The types of directives and pipes that are used in a component's template may be emitted into the partial declaration wrapped inside a closure, which is needed when the type is declared later in the module. This poses a problem for JIT compilation of partial declarations, as this closure is indistinguishable from a class reference itself. To mark the forward reference function as such, this commit changes the partial declaration codegen to emit a `forwardRef` invocation wrapped around the closure, which ensures that the closure is properly tagged as a forward reference. This allows the forward reference to be treated as such during JIT compilation. PR Close #40117
This commit is contained in:
parent
fc1cd07eb0
commit
e23fd1f382
|
@ -100,6 +100,21 @@ export class BabelAstHost implements AstHost<t.Expression> {
|
|||
return stmt.argument;
|
||||
}
|
||||
|
||||
isCallExpression = t.isCallExpression;
|
||||
parseCallee(call: t.Expression): t.Expression {
|
||||
assert(call, t.isCallExpression, 'a call expression');
|
||||
assert(call.callee, t.isExpression, 'an expression');
|
||||
return call.callee;
|
||||
}
|
||||
parseArguments(call: t.Expression): t.Expression[] {
|
||||
assert(call, t.isCallExpression, 'a call expression');
|
||||
return call.arguments.map(arg => {
|
||||
assert(arg, isNotSpreadArgument, 'argument not to use spread syntax');
|
||||
assert(arg, t.isExpression, 'argument to be an expression');
|
||||
return arg;
|
||||
});
|
||||
}
|
||||
|
||||
getRange(node: t.Expression): Range {
|
||||
if (node.loc == null || node.start === null || node.end === null) {
|
||||
throw new FatalLinkerError(
|
||||
|
@ -138,3 +153,15 @@ function isNotSpreadElement(e: t.Expression|t.SpreadElement): e is t.Expression
|
|||
function isPropertyName(e: t.Expression): e is t.Identifier|t.StringLiteral|t.NumericLiteral {
|
||||
return t.isIdentifier(e) || t.isStringLiteral(e) || t.isNumericLiteral(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* The declared type of an argument to a call expression.
|
||||
*/
|
||||
type ArgumentType = t.CallExpression['arguments'][number];
|
||||
|
||||
/**
|
||||
* Return true if the argument is not a spread element.
|
||||
*/
|
||||
function isNotSpreadArgument(arg: ArgumentType): arg is Exclude<ArgumentType, t.SpreadElement> {
|
||||
return !t.isSpreadElement(arg);
|
||||
}
|
||||
|
|
|
@ -263,6 +263,55 @@ describe('BabelAstHost', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isCallExpression()', () => {
|
||||
it('should return true if the expression is a call expression', () => {
|
||||
expect(host.isCallExpression(expr('foo()'))).toBe(true);
|
||||
expect(host.isCallExpression(expr('foo.bar()'))).toBe(true);
|
||||
expect(host.isCallExpression(expr('(foo)(1)'))).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the expression is not a call expression', () => {
|
||||
expect(host.isCallExpression(expr('[]'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('"moo"'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\'moo\''))).toBe(false);
|
||||
expect(host.isCallExpression(expr('someIdentifier'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('42'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('{}'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('null'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\'a\' + \'b\''))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\`moo\`'))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseCallee()', () => {
|
||||
it('should return the callee expression', () => {
|
||||
expect(host.parseCallee(expr('foo()'))).toEqual(expr('foo'));
|
||||
expect(host.parseCallee(expr('foo.bar()'))).toEqual(expr('foo.bar'));
|
||||
});
|
||||
|
||||
it('should error if the node is not a call expression', () => {
|
||||
expect(() => host.parseCallee(expr('[]')))
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseArguments()', () => {
|
||||
it('should return the arguments as an array of expressions', () => {
|
||||
expect(host.parseArguments(expr('foo(12, [])'))).toEqual([expr('12'), expr('[]')]);
|
||||
expect(host.parseArguments(expr('foo.bar()'))).toEqual([]);
|
||||
});
|
||||
|
||||
it('should error if the node is not a call expression', () => {
|
||||
expect(() => host.parseArguments(expr('[]')))
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
|
||||
it('should error if an argument uses spread syntax', () => {
|
||||
expect(() => host.parseArguments(expr('foo(1, ...[])')))
|
||||
.toThrowError('Unsupported syntax, expected argument not to use spread syntax.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRange()', () => {
|
||||
it('should extract the range from the expression', () => {
|
||||
const file = parse('// preamble\nx = \'moo\';');
|
||||
|
|
|
@ -74,6 +74,21 @@ export interface AstHost<TExpression> {
|
|||
*/
|
||||
parseReturnValue(fn: TExpression): TExpression;
|
||||
|
||||
/**
|
||||
* Return true if the given expression is a call expression, or false otherwise.
|
||||
*/
|
||||
isCallExpression(node: TExpression): boolean;
|
||||
/**
|
||||
* Returns the expression that is called in the provided call expression, or throw if it is not
|
||||
* a call expression.
|
||||
*/
|
||||
parseCallee(call: TExpression): TExpression;
|
||||
/**
|
||||
* Returns the argument expressions for the provided call expression, or throw if it is not
|
||||
* a call expression.
|
||||
*/
|
||||
parseArguments(call: TExpression): TExpression[];
|
||||
|
||||
/**
|
||||
* Compute the location range of the expression in the source file, to be used for source-mapping.
|
||||
*/
|
||||
|
|
|
@ -295,6 +295,19 @@ export class AstValue<T, TExpression> {
|
|||
return new AstValue(this.host.parseReturnValue(this.expression), this.host);
|
||||
}
|
||||
|
||||
isCallExpression(): boolean {
|
||||
return this.host.isCallExpression(this.expression);
|
||||
}
|
||||
|
||||
getCallee(): AstValue<unknown, TExpression> {
|
||||
return new AstValue(this.host.parseCallee(this.expression), this.host);
|
||||
}
|
||||
|
||||
getArguments(): AstValue<unknown, TExpression>[] {
|
||||
const args = this.host.parseArguments(this.expression);
|
||||
return args.map(arg => new AstValue(arg, this.host));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the `TExpression` of this value wrapped in a `WrappedNodeExpr`.
|
||||
*/
|
||||
|
|
|
@ -109,6 +109,21 @@ export class TypeScriptAstHost implements AstHost<ts.Expression> {
|
|||
return stmt.expression;
|
||||
}
|
||||
|
||||
isCallExpression = ts.isCallExpression;
|
||||
|
||||
parseCallee(call: ts.Expression): ts.Expression {
|
||||
assert(call, ts.isCallExpression, 'a call expression');
|
||||
return call.expression;
|
||||
}
|
||||
|
||||
parseArguments(call: ts.Expression): ts.Expression[] {
|
||||
assert(call, ts.isCallExpression, 'a call expression');
|
||||
return call.arguments.map(arg => {
|
||||
assert(arg, isNotSpreadElement, 'argument not to use spread syntax');
|
||||
return arg;
|
||||
});
|
||||
}
|
||||
|
||||
getRange(node: ts.Expression): Range {
|
||||
const file = node.getSourceFile();
|
||||
if (file === undefined) {
|
||||
|
|
|
@ -73,10 +73,12 @@ export function toR3ComponentMeta<TExpression>(
|
|||
const selector = directiveExpr.getString('selector');
|
||||
|
||||
let typeExpr = type.getOpaque();
|
||||
if (type.isFunction()) {
|
||||
typeExpr = type.getFunctionReturnValue().getOpaque();
|
||||
const forwardRefType = extractForwardRef(type);
|
||||
if (forwardRefType !== null) {
|
||||
typeExpr = forwardRefType;
|
||||
wrapDirectivesAndPipesInClosure = true;
|
||||
}
|
||||
|
||||
return {
|
||||
type: typeExpr,
|
||||
selector: selector,
|
||||
|
@ -95,12 +97,13 @@ export function toR3ComponentMeta<TExpression>(
|
|||
|
||||
let pipes = new Map<string, o.Expression>();
|
||||
if (metaObj.has('pipes')) {
|
||||
pipes = metaObj.getObject('pipes').toMap(value => {
|
||||
if (value.isFunction()) {
|
||||
pipes = metaObj.getObject('pipes').toMap(pipe => {
|
||||
const forwardRefType = extractForwardRef(pipe);
|
||||
if (forwardRefType !== null) {
|
||||
wrapDirectivesAndPipesInClosure = true;
|
||||
return value.getFunctionReturnValue().getOpaque();
|
||||
return forwardRefType;
|
||||
} else {
|
||||
return value.getOpaque();
|
||||
return pipe.getOpaque();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -205,3 +208,35 @@ function getTemplateRange<TExpression>(
|
|||
startCol: startCol + 1,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the type reference expression from a `forwardRef` function call. For example, the
|
||||
* expression `forwardRef(function() { return FooDir; })` returns `FooDir`. Note that this
|
||||
* expression is required to be wrapped in a closure, as otherwise the forward reference would be
|
||||
* resolved before initialization.
|
||||
*/
|
||||
function extractForwardRef<TExpression>(expr: AstValue<unknown, TExpression>):
|
||||
o.WrappedNodeExpr<TExpression>|null {
|
||||
if (!expr.isCallExpression()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const callee = expr.getCallee();
|
||||
if (callee.getSymbolName() !== 'forwardRef') {
|
||||
throw new FatalLinkerError(
|
||||
callee.expression, 'Unsupported directive type, expected forwardRef or a type reference');
|
||||
}
|
||||
|
||||
const args = expr.getArguments();
|
||||
if (args.length !== 1) {
|
||||
throw new FatalLinkerError(expr, 'Unsupported forwardRef call, expected a single argument');
|
||||
}
|
||||
|
||||
const wrapperFn = args[0] as AstValue<Function, TExpression>;
|
||||
if (!wrapperFn.isFunction()) {
|
||||
throw new FatalLinkerError(
|
||||
wrapperFn, 'Unsupported forwardRef call, expected a function argument');
|
||||
}
|
||||
|
||||
return wrapperFn.getFunctionReturnValue().getOpaque();
|
||||
}
|
||||
|
|
|
@ -359,6 +359,52 @@ describe('AstValue', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isCallExpression', () => {
|
||||
it('should return true if the value represents a call expression', () => {
|
||||
const callExpr = factory.createCallExpression(factory.createIdentifier('foo'), [], false);
|
||||
expect(createAstValue<Function>(callExpr).isCallExpression()).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the value does not represent a call expression', () => {
|
||||
const fooExpr = factory.createIdentifier('foo');
|
||||
expect(createAstValue<Function>(fooExpr).isCallExpression()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCallee', () => {
|
||||
it('should return the callee expression as a value', () => {
|
||||
const callExpr = factory.createCallExpression(factory.createIdentifier('foo'), [], false);
|
||||
expect(createAstValue<Function>(callExpr).getCallee())
|
||||
.toEqual(createAstValue(factory.createIdentifier('foo')));
|
||||
});
|
||||
|
||||
it('should throw an error if the value is not a call expression', () => {
|
||||
expect(() => createAstValue<number>(factory.createLiteral(42)).getCallee())
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getArguments', () => {
|
||||
it('should return the arguments as an array of values', () => {
|
||||
const callExpr = factory.createCallExpression(
|
||||
factory.createIdentifier('foo'),
|
||||
[
|
||||
factory.createLiteral(1),
|
||||
factory.createLiteral(2),
|
||||
],
|
||||
false);
|
||||
expect(createAstValue<Function>(callExpr).getArguments()).toEqual([
|
||||
createAstValue(factory.createLiteral(1)),
|
||||
createAstValue(factory.createLiteral(2)),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should throw an error if the value is not a call expression', () => {
|
||||
expect(() => createAstValue<number>(factory.createLiteral(42)).getArguments())
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOpaque()', () => {
|
||||
it('should return the value wrapped in a `WrappedNodeExpr`', () => {
|
||||
expect(createAstValue(factory.createLiteral(42)).getOpaque())
|
||||
|
|
|
@ -257,6 +257,59 @@ describe('TypeScriptAstHost', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isCallExpression()', () => {
|
||||
it('should return true if the expression is a call expression', () => {
|
||||
expect(host.isCallExpression(expr('foo()'))).toBe(true);
|
||||
expect(host.isCallExpression(expr('foo.bar()'))).toBe(true);
|
||||
expect(host.isCallExpression(expr('(foo)(1)'))).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the expression is not a call expression', () => {
|
||||
expect(host.isCallExpression(expr('[]'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('"moo"'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\'moo\''))).toBe(false);
|
||||
expect(host.isCallExpression(expr('someIdentifier'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('42'))).toBe(false);
|
||||
expect(host.isCallExpression(rhs('x = {}'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('null'))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\'a\' + \'b\''))).toBe(false);
|
||||
expect(host.isCallExpression(expr('\`moo\`'))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseCallee()', () => {
|
||||
it('should return the callee expression', () => {
|
||||
const foo = jasmine.objectContaining({text: 'foo', kind: ts.SyntaxKind.Identifier});
|
||||
const bar = jasmine.objectContaining({kind: ts.SyntaxKind.PropertyAccessExpression});
|
||||
expect(host.parseCallee(expr('foo()'))).toEqual(foo);
|
||||
expect(host.parseCallee(expr('foo.bar()'))).toEqual(bar);
|
||||
});
|
||||
|
||||
it('should error if the node is not a call expression', () => {
|
||||
expect(() => host.parseCallee(expr('[]')))
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseArguments()', () => {
|
||||
it('should return the arguments as an array of expressions', () => {
|
||||
const arg1 = jasmine.objectContaining({text: '12', kind: ts.SyntaxKind.NumericLiteral});
|
||||
const arg2 = jasmine.objectContaining({kind: ts.SyntaxKind.ArrayLiteralExpression});
|
||||
expect(host.parseArguments(expr('foo(12, [])'))).toEqual([arg1, arg2]);
|
||||
expect(host.parseArguments(expr('foo.bar()'))).toEqual([]);
|
||||
});
|
||||
|
||||
it('should error if the node is not a call expression', () => {
|
||||
expect(() => host.parseArguments(expr('[]')))
|
||||
.toThrowError('Unsupported syntax, expected a call expression.');
|
||||
});
|
||||
|
||||
it('should error if an argument uses spread syntax', () => {
|
||||
expect(() => host.parseArguments(expr('foo(1, ...[])')))
|
||||
.toThrowError('Unsupported syntax, expected argument not to use spread syntax.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRange()', () => {
|
||||
it('should extract the range from the expression', () => {
|
||||
const moo = rhs('// preamble\nx = \'moo\';');
|
||||
|
|
|
@ -8,7 +8,7 @@ export class HostBindingComp {
|
|||
HostBindingComp.ɵfac = function HostBindingComp_Factory(t) { return new (t || HostBindingComp)(); };
|
||||
HostBindingComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: HostBindingComp, selector: "host-binding-comp", ngImport: i0, template: { source: `
|
||||
<my-forward-directive></my-forward-directive>
|
||||
`, isInline: true }, directives: [{ type: function () { return MyForwardDirective; }, selector: "my-forward-directive" }] });
|
||||
`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return MyForwardDirective; }), selector: "my-forward-directive" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HostBindingComp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -59,7 +59,7 @@ export class HostBindingComp {
|
|||
HostBindingComp.ɵfac = function HostBindingComp_Factory(t) { return new (t || HostBindingComp)(); };
|
||||
HostBindingComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: HostBindingComp, selector: "host-binding-comp", ngImport: i0, template: { source: `
|
||||
<div [attr.style]="{} | my_forward_pipe">...</div>
|
||||
`, isInline: true }, pipes: { "my_forward_pipe": function () { return MyForwardPipe; } } });
|
||||
`, isInline: true }, pipes: { "my_forward_pipe": i0.forwardRef(function () { return MyForwardPipe; }) } });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HostBindingComp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -34,7 +34,7 @@ export class ViewQueryComponent {
|
|||
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
|
||||
ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true }, { propertyName: "someDirs", predicate: SomeDirective, descendants: true }], ngImport: i0, template: { source: `
|
||||
<div someDir></div>
|
||||
`, isInline: true }, directives: [{ type: function () { return SomeDirective; }, selector: "[someDir]" }] });
|
||||
`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -168,7 +168,7 @@ export class ViewQueryComponent {
|
|||
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
|
||||
ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true, static: true }, { propertyName: "foo", first: true, predicate: ["foo"], descendants: true }], ngImport: i0, template: { source: `
|
||||
<div someDir></div>
|
||||
`, isInline: true }, directives: [{ type: function () { return SomeDirective; }, selector: "[someDir]" }] });
|
||||
`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -361,7 +361,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
|
|||
<content-query-component>
|
||||
<div someDir></div>
|
||||
</content-query-component>
|
||||
`, isInline: true }, directives: [{ type: function () { return ContentQueryComponent; }, selector: "content-query-component" }, { type: function () { return SomeDirective; }, selector: "[someDir]" }] });
|
||||
`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -518,7 +518,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
|
|||
<content-query-component>
|
||||
<div someDir></div>
|
||||
</content-query-component>
|
||||
`, isInline: true }, directives: [{ type: function () { return ContentQueryComponent; }, selector: "content-query-component" }, { type: function () { return SomeDirective; }, selector: "[someDir]" }] });
|
||||
`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -53,7 +53,7 @@ export class MyComponent {
|
|||
}
|
||||
}
|
||||
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `<svg><g *for="let item of items"><circle></circle></g></svg>`, isInline: true }, directives: [{ type: function () { return ForOfDirective; }, selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `<svg><g *for="let item of items"><circle></circle></g></svg>`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return ForOfDirective; }), selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -143,7 +143,7 @@ export class MyComponent {
|
|||
}
|
||||
}
|
||||
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `<ul><li *for="let item of items">{{item.name}}</li></ul>`, isInline: true }, directives: [{ type: function () { return ForOfDirective; }, selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `<ul><li *for="let item of items">{{item.name}}</li></ul>`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return ForOfDirective; }), selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -246,7 +246,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>`, isInline: true }, directives: [{ type: function () { return ForOfDirective; }, selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
</ul>`, isInline: true }, directives: [{ type: i0.forwardRef(function () { return ForOfDirective; }), selector: "[forOf]", inputs: ["forOf"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -9,7 +9,7 @@ export class MyApp {
|
|||
}
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: { source: '<todo [data]="list"></todo>', isInline: true }, directives: [{ type: function () { return TodoComponent; }, selector: "todo", inputs: ["data"] }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: { source: '<todo [data]="list"></todo>', isInline: true }, directives: [{ type: i0.forwardRef(function () { return TodoComponent; }), selector: "todo", inputs: ["data"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-app', template: '<todo [data]="list"></todo>' }]
|
||||
|
|
|
@ -334,7 +334,7 @@ import * as i0 from "@angular/core";
|
|||
export class TestCmp {
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: '<div>{{200.3 | percent : 2 }}</div>', isInline: true }, pipes: { "percent": function () { return PercentPipe; } } });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: '<div>{{200.3 | percent : 2 }}</div>', isInline: true }, pipes: { "percent": i0.forwardRef(function () { return PercentPipe; }) } });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -364,7 +364,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: interpolation_with_pipe.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"interpolation_with_pipe.js","sourceRoot":"","sources":["../interpolation_with_pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;;AAMvE,MAAM,OAAO,OAAO;;8DAAP,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,6DAMpC,WAAW;uFAJX,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAKD,MAAM,OAAO,WAAW;IACtB,SAAS,KAAI,CAAC;;sEADH,WAAW;6DAAX,WAAW;uFAAX,WAAW;cADvB,IAAI;eAAC,EAAC,IAAI,EAAE,SAAS,EAAC;;AAMvB,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBATT,OAAO,EAIP,WAAW;uFAKX,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAC"}
|
||||
{"version":3,"file":"interpolation_with_pipe.js","sourceRoot":"","sources":["../interpolation_with_pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;;AAMvE,MAAM,OAAO,OAAO;;8DAAP,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,2EAMpC,WAAW;uFAJX,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAKD,MAAM,OAAO,WAAW;IACtB,SAAS,KAAI,CAAC;;sEADH,WAAW;6DAAX,WAAW;uFAAX,WAAW;cADvB,IAAI;eAAC,EAAC,IAAI,EAAE,SAAS,EAAC;;AAMvB,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBATT,OAAO,EAIP,WAAW;uFAKX,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: interpolation_with_pipe.d.ts
|
||||
****************************************************************************************************/
|
||||
|
@ -392,7 +392,7 @@ import * as i0 from "@angular/core";
|
|||
export class TestCmp {
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: '<div>{{200.3 | percent : 2 }}</div>', isInline: true }, pipes: { "percent": function () { return PercentPipe; } } });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: '<div>{{200.3 | percent : 2 }}</div>', isInline: true }, pipes: { "percent": i0.forwardRef(function () { return PercentPipe; }) } });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -422,7 +422,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: interpolation_with_pipe.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"interpolation_with_pipe.js","sourceRoot":"","sources":["../interpolation_with_pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;;AAMvE,MAAM,OAAO,OAAO;;8DAAP,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,6DAMpC,WAAW;uFAJX,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAKD,MAAM,OAAO,WAAW;IACtB,SAAS,KAAI,CAAC;;sEADH,WAAW;6DAAX,WAAW;uFAAX,WAAW;cADvB,IAAI;eAAC,EAAC,IAAI,EAAE,SAAS,EAAC;;AAMvB,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBATT,OAAO,EAIP,WAAW;uFAKX,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAC"}
|
||||
{"version":3,"file":"interpolation_with_pipe.js","sourceRoot":"","sources":["../interpolation_with_pipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAgB,MAAM,eAAe,CAAC;;AAMvE,MAAM,OAAO,OAAO;;8DAAP,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,2EAMpC,WAAW;uFAJX,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAKD,MAAM,OAAO,WAAW;IACtB,SAAS,KAAI,CAAC;;sEADH,WAAW;6DAAX,WAAW;uFAAX,WAAW;cADvB,IAAI;eAAC,EAAC,IAAI,EAAE,SAAS,EAAC;;AAMvB,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBATT,OAAO,EAIP,WAAW;uFAKX,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: interpolation_with_pipe.d.ts
|
||||
****************************************************************************************************/
|
||||
|
@ -857,7 +857,7 @@ export class TestCmp {
|
|||
}
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input [(ngModel)]="name">', isInline: true }, directives: [{ type: function () { return NgModelDirective; }, selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input [(ngModel)]="name">', isInline: true }, directives: [{ type: i0.forwardRef(function () { return NgModelDirective; }), selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -894,7 +894,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_simple.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"two_way_binding_simple.js","sourceRoot":"","sources":["../two_way_binding_simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,kCAAkC,8DAOjC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,kCAAkC;aAC7C;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
{"version":3,"file":"two_way_binding_simple.js","sourceRoot":"","sources":["../two_way_binding_simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,kCAAkC,4EAOjC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,kCAAkC;aAC7C;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_simple.d.ts
|
||||
****************************************************************************************************/
|
||||
|
@ -927,7 +927,7 @@ export class TestCmp {
|
|||
}
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input [(ngModel)]="name">', isInline: true }, directives: [{ type: function () { return NgModelDirective; }, selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input [(ngModel)]="name">', isInline: true }, directives: [{ type: i0.forwardRef(function () { return NgModelDirective; }), selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -964,7 +964,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_simple.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"two_way_binding_simple.js","sourceRoot":"","sources":["../two_way_binding_simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,kCAAkC,8DAOjC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,kCAAkC;aAC7C;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
{"version":3,"file":"two_way_binding_simple.js","sourceRoot":"","sources":["../two_way_binding_simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,kCAAkC,4EAOjC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,kCAAkC;aAC7C;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_simple.d.ts
|
||||
****************************************************************************************************/
|
||||
|
@ -997,7 +997,7 @@ export class TestCmp {
|
|||
}
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input bindon-ngModel="name">', isInline: true }, directives: [{ type: function () { return NgModelDirective; }, selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input bindon-ngModel="name">', isInline: true }, directives: [{ type: i0.forwardRef(function () { return NgModelDirective; }), selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -1034,7 +1034,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_longhand.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"two_way_binding_longhand.js","sourceRoot":"","sources":["../two_way_binding_longhand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,8DAOpC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
{"version":3,"file":"two_way_binding_longhand.js","sourceRoot":"","sources":["../two_way_binding_longhand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,4EAOpC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_longhand.d.ts
|
||||
****************************************************************************************************/
|
||||
|
@ -1067,7 +1067,7 @@ export class TestCmp {
|
|||
}
|
||||
}
|
||||
TestCmp.ɵfac = function TestCmp_Factory(t) { return new (t || TestCmp)(); };
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input bindon-ngModel="name">', isInline: true }, directives: [{ type: function () { return NgModelDirective; }, selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
TestCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: TestCmp, selector: "test-cmp", ngImport: i0, template: { source: 'Name: <input bindon-ngModel="name">', isInline: true }, directives: [{ type: i0.forwardRef(function () { return NgModelDirective; }), selector: "[ngModel]", inputs: ["ngModel"], outputs: ["ngModelChanges"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestCmp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -1104,7 +1104,7 @@ AppModule.ɵinj = i0.ɵɵdefineInjector({ factory: function AppModule_Factory(t)
|
|||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_longhand.js.map
|
||||
****************************************************************************************************/
|
||||
{"version":3,"file":"two_way_binding_longhand.js","sourceRoot":"","sources":["../two_way_binding_longhand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,8DAOpC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
{"version":3,"file":"two_way_binding_longhand.js","sourceRoot":"","sources":["../two_way_binding_longhand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;;AAM1F,MAAM,OAAO,OAAO;IAJpB;QAKE,SAAI,GAAW,EAAE,CAAC;KACnB;;8DAFY,OAAO;6EAAP,OAAO,0DAFR,qCAAqC,4EAOpC,gBAAgB;uFALhB,OAAO;cAJnB,SAAS;eAAC;gBACT,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,qCAAqC;aAChD;;AAMD,MAAM,OAAO,gBAAgB;IAD7B;QAEW,YAAO,GAAW,EAAE,CAAC;QACpB,mBAAc,GAAyB,IAAI,YAAY,EAAE,CAAC;KACrE;;gFAHY,gBAAgB;sFAAhB,gBAAgB;uFAAhB,gBAAgB;cAD5B,SAAS;eAAC,EAAC,QAAQ,EAAE,WAAW,EAAC;gBAEvB,OAAO;kBAAf,KAAK;YACI,cAAc;kBAAvB,MAAM;;AAIT,MAAM,OAAO,SAAS;;6CAAT,SAAS;iGAAT,SAAS;wFAAT,SAAS,mBAXT,OAAO,EAKP,gBAAgB;uFAMhB,SAAS;cADrB,QAAQ;eAAC,EAAC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAC"}
|
||||
/****************************************************************************************************
|
||||
* PARTIAL FILE: two_way_binding_longhand.d.ts
|
||||
****************************************************************************************************/
|
||||
|
|
|
@ -155,7 +155,8 @@ export interface R3DeclareComponentMetadata extends R3DeclareDirectiveMetadata {
|
|||
selector: string;
|
||||
|
||||
/**
|
||||
* Reference to the directive class (possibly a forward reference).
|
||||
* Reference to the directive class (possibly a forward reference wrapped in a `forwardRef`
|
||||
* invocation).
|
||||
*/
|
||||
type: o.Expression | (() => o.Expression);
|
||||
|
||||
|
@ -176,8 +177,8 @@ export interface R3DeclareComponentMetadata extends R3DeclareDirectiveMetadata {
|
|||
}[];
|
||||
|
||||
/**
|
||||
* A map of pipe names to an expression referencing the pipe type (possibly a forward reference)
|
||||
* which are used in the template.
|
||||
* A map of pipe names to an expression referencing the pipe type (possibly a forward reference
|
||||
* wrapped in a `forwardRef` invocation) which are used in the template.
|
||||
*/
|
||||
pipes?: {[pipeName: string]: o.Expression|(() => o.Expression)};
|
||||
|
||||
|
|
|
@ -91,9 +91,8 @@ function compileTemplateDefinition(template: ParsedTemplate): o.LiteralMapExpr {
|
|||
* individual directives. If the component does not use any directives, then null is returned.
|
||||
*/
|
||||
function compileUsedDirectiveMetadata(meta: R3ComponentMetadata): o.LiteralArrayExpr|null {
|
||||
const wrapType = meta.wrapDirectivesAndPipesInClosure ?
|
||||
(expr: o.Expression) => o.fn([], [new o.ReturnStatement(expr)]) :
|
||||
(expr: o.Expression) => expr;
|
||||
const wrapType =
|
||||
meta.wrapDirectivesAndPipesInClosure ? generateForwardRef : (expr: o.Expression) => expr;
|
||||
|
||||
return toOptionalLiteralArray(meta.directives, directive => {
|
||||
const dirMeta = new DefinitionMap<R3UsedDirectiveMetadata>();
|
||||
|
@ -116,9 +115,8 @@ function compileUsedPipeMetadata(meta: R3ComponentMetadata): o.LiteralMapExpr|nu
|
|||
return null;
|
||||
}
|
||||
|
||||
const wrapType = meta.wrapDirectivesAndPipesInClosure ?
|
||||
(expr: o.Expression) => o.fn([], [new o.ReturnStatement(expr)]) :
|
||||
(expr: o.Expression) => expr;
|
||||
const wrapType =
|
||||
meta.wrapDirectivesAndPipesInClosure ? generateForwardRef : (expr: o.Expression) => expr;
|
||||
|
||||
const entries = [];
|
||||
for (const [name, pipe] of meta.pipes) {
|
||||
|
@ -126,3 +124,7 @@ function compileUsedPipeMetadata(meta: R3ComponentMetadata): o.LiteralMapExpr|nu
|
|||
}
|
||||
return o.literalMap(entries);
|
||||
}
|
||||
|
||||
function generateForwardRef(expr: o.Expression): o.Expression {
|
||||
return o.importExpr(R3.forwardRef).callFn([o.fn([], [new o.ReturnStatement(expr)])]);
|
||||
}
|
||||
|
|
|
@ -229,6 +229,8 @@ export class Identifiers {
|
|||
static templateRefExtractor:
|
||||
o.ExternalReference = {name: 'ɵɵtemplateRefExtractor', moduleName: CORE};
|
||||
|
||||
static forwardRef: o.ExternalReference = {name: 'forwardRef', moduleName: CORE};
|
||||
|
||||
static resolveWindow: o.ExternalReference = {name: 'ɵɵresolveWindow', moduleName: CORE};
|
||||
static resolveDocument: o.ExternalReference = {name: 'ɵɵresolveDocument', moduleName: CORE};
|
||||
static resolveBody: o.ExternalReference = {name: 'ɵɵresolveBody', moduleName: CORE};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {forwardRef} from '../../di/forward_ref';
|
||||
import {ɵɵinject, ɵɵinvalidFactoryDep} from '../../di/injector_compatibility';
|
||||
import {ɵɵdefineInjectable, ɵɵdefineInjector} from '../../di/interface/defs';
|
||||
import * as sanitization from '../../sanitization/sanitization';
|
||||
|
@ -167,4 +168,6 @@ export const angularCoreEnv: {[name: string]: Function} =
|
|||
'ɵɵsanitizeUrlOrResourceUrl': sanitization.ɵɵsanitizeUrlOrResourceUrl,
|
||||
'ɵɵtrustConstantHtml': sanitization.ɵɵtrustConstantHtml,
|
||||
'ɵɵtrustConstantResourceUrl': sanitization.ɵɵtrustConstantResourceUrl,
|
||||
|
||||
'forwardRef': forwardRef,
|
||||
}))();
|
||||
|
|
Loading…
Reference in New Issue