Skip to content

Commit

Permalink
refactor(compiler): Support unary ops in template pipeline
Browse files Browse the repository at this point in the history
Template Pipeline can now ingest and emit unary ops, such as `+` and `-`.
  • Loading branch information
dylhunn committed Dec 6, 2023
1 parent 1f01cf3 commit e947159
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,50 @@ export declare class TodoModule {
static ɵinj: i0.ɵɵInjectorDeclaration<TodoModule>;
}

/****************************************************************************************************
* PARTIAL FILE: operators.js
****************************************************************************************************/
import { Component, NgModule } from '@angular/core';
import * as i0 from "@angular/core";
export class MyApp {
}
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
{{ 1 + 2 }}
{{ (1 % 2) + 3 / 4 * 5 }}
{{ +1 }}
`, isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
type: Component,
args: [{
template: `
{{ 1 + 2 }}
{{ (1 % 2) + 3 / 4 * 5 }}
{{ +1 }}
`
}]
}] });
export class MyModule {
}
MyModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
MyModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, declarations: [MyApp] });
MyModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, decorators: [{
type: NgModule,
args: [{ declarations: [MyApp] }]
}] });

/****************************************************************************************************
* PARTIAL FILE: operators.d.ts
****************************************************************************************************/
import * as i0 from "@angular/core";
export declare class MyApp {
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
}
export declare class MyModule {
static ɵfac: i0.ɵɵFactoryDeclaration<MyModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<MyModule, [typeof MyApp], never, never>;
static ɵinj: i0.ɵɵInjectorDeclaration<MyModule>;
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@
"failureMessage": "Incorrect template"
}
]
},
{
"description": "should handle binary and unary operators",
"inputFiles": [
"operators.ts"
],
"expectations": [
{
"files": [
{
"expected": "operators_template.js",
"generated": "operators.js"
}
],
"failureMessage": "Incorrect template"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Component, NgModule} from '@angular/core';

@Component({
template: `
{{ 1 + 2 }}
{{ (1 % 2) + 3 / 4 * 5 }}
{{ +1 }}
`
})
export class MyApp {
}

@NgModule({declarations: [MyApp]})
export class MyModule {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
template: function MyApp_Template(rf, $ctx$) {
if (rf & 1) {
$i0$.ɵɵtext(0);
} if (rf & 2) {
i0.ɵɵtextInterpolate3(" ", 1 + 2, " ", 1 % 2 + 3 / 4 * 5, " ", +1, "\n");
}
}

2 changes: 2 additions & 0 deletions packages/compiler/src/template/pipeline/ir/src/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,8 @@ export function transformExpressionsInExpression(
} else if (expr instanceof o.BinaryOperatorExpr) {
expr.lhs = transformExpressionsInExpression(expr.lhs, transform, flags);
expr.rhs = transformExpressionsInExpression(expr.rhs, transform, flags);
} else if (expr instanceof o.UnaryOperatorExpr) {
expr.expr = transformExpressionsInExpression(expr.expr, transform, flags);
} else if (expr instanceof o.ReadPropExpr) {
expr.receiver = transformExpressionsInExpression(expr.receiver, transform, flags);
} else if (expr instanceof o.ReadKeyExpr) {
Expand Down
13 changes: 12 additions & 1 deletion packages/compiler/src/template/pipeline/src/ingest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,18 @@ function convertAst(
} else if (ast instanceof e.LiteralPrimitive) {
return o.literal(ast.value, undefined, convertSourceSpan(ast.span, baseSourceSpan));
} else if (ast instanceof e.Unary) {
throw new Error('TODO: Support unary operations, which extend binary ops');
switch (ast.operator) {
case '+':
return new o.UnaryOperatorExpr(
o.UnaryOperator.Plus, convertAst(ast.expr, job, baseSourceSpan), undefined,
convertSourceSpan(ast.span, baseSourceSpan));
case '-':
return new o.UnaryOperatorExpr(
o.UnaryOperator.Minus, convertAst(ast.expr, job, baseSourceSpan), undefined,
convertSourceSpan(ast.span, baseSourceSpan));
default:
throw new Error(`AssertionError: unknown unary operator ${ast.operator}`);
}
} else if (ast instanceof e.Binary) {
const operator = BINARY_OPERATORS.get(ast.operation);
if (operator === undefined) {
Expand Down

0 comments on commit e947159

Please sign in to comment.