diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js index f46b77826f14ea..fde5a0a9b82159 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js @@ -63,3 +63,50 @@ export declare class TodoModule { static ɵinj: i0.ɵɵInjectorDeclaration; } +/**************************************************************************************************** + * 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; + static ɵcmp: i0.ɵɵComponentDeclaration; +} +export declare class MyModule { + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵmod: i0.ɵɵNgModuleDeclaration; + static ɵinj: i0.ɵɵInjectorDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/TEST_CASES.json index 9167bba39aa632..aed83968a2bb9f 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/TEST_CASES.json @@ -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" + } + ] } ] } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators.ts new file mode 100644 index 00000000000000..6c6b08283c6d7f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators.ts @@ -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 { +} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators_template.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators_template.js new file mode 100644 index 00000000000000..c1a3d7fb87d60d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/operators_template.js @@ -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"); + } + } + \ No newline at end of file diff --git a/packages/compiler/src/template/pipeline/ir/src/expression.ts b/packages/compiler/src/template/pipeline/ir/src/expression.ts index 53650cb62f2f15..143a21a7bdbd28 100644 --- a/packages/compiler/src/template/pipeline/ir/src/expression.ts +++ b/packages/compiler/src/template/pipeline/ir/src/expression.ts @@ -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) { diff --git a/packages/compiler/src/template/pipeline/src/ingest.ts b/packages/compiler/src/template/pipeline/src/ingest.ts index f267424e5067e8..90843c73cc7935 100644 --- a/packages/compiler/src/template/pipeline/src/ingest.ts +++ b/packages/compiler/src/template/pipeline/src/ingest.ts @@ -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) {