Skip to content

refactor(compiler-cli): align NGP ExpressionPrinter formatting with ngtsc TS printer - #71432

Open
JeanMeche wants to merge 1 commit into
angular:mainfrom
JeanMeche:refactor/ngp-printer-parity
Open

JeanMeche wants to merge 1 commit into
angular:mainfrom
JeanMeche:refactor/ngp-printer-parity

Conversation

@JeanMeche

Copy link
Copy Markdown
Member

Summary

Resolves the TODO(ngp-parity) in packages/compiler-cli/src/ngtsc/testing/src/ngp_emit_normalizer.ts by aligning NGP's ExpressionPrinter (packages/compiler-cli/preprocessor/src/output_ast_printer.ts) with ngtsc's TypeScript AST printer (ExpressionTranslatorVisitor + TypeScriptAstFactory) and removing the corresponding AST/regex post-processing hacks from test normalizers:

  1. Operator-precedence-aware parenthesization (EmitterVisitor):
    • Tracks AssignmentExpression-permissive positions (top-level ExpressionPrinter.print(), ExpressionStatement, ReturnStatement, DeclareVarStmt initializer, IfStmt condition, call/new/comma-separated argument lists, array/object/template literal elements, spread expressions, index accesses, arrow concise bodies, and ternary branches) via withUnparenthesized().
    • Uses JS/TS operator precedence, associativity, and ??/&&/|| mixing rules (canOmitBinaryOperandParens) to omit redundant parentheses on BinaryOperatorExpr, ConditionalExpr, and UnaryOperatorExpr while preserving explicit ParenthesizedExpr nodes and required precedence/associativity grouping.
  2. Single-line FunctionExpr formatting & argument comma spacing:
    • Formats FunctionExpr nodes whose body is a single ReturnStatement without leading comments on a single line (function(...) { return ...; }), matching TypeScriptAstFactory.createFunctionExpression.
    • Separates comma-delimited expression lists with ', ' in visitAllExpressions.
  3. Test normalizer cleanup (ngp_emit_normalizer.ts, expect_emit.ts, compliance_spec.ts):
    • Removes stripRedundantClarifyingParens, transformOutsideStringLikeTokens, Prettier re-formatting in compliance_spec.ts, and the ad-hoc parenthesization/factory/comma regexes from normalizeNgpEmitForComparison and normalizeNgpOutputFile.
    • Canonicalizes single-quoted string literals inside ${...} template literal interpolations (such as $localize placeholder expressions) in canonicalizeStringQuotes.

@angular-robot angular-robot Bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Oct 19, 2026
@ngbot ngbot Bot added this to the Backlog milestone Oct 19, 2026
@JeanMeche
JeanMeche force-pushed the refactor/ngp-printer-parity branch from 78e1501 to 8f33588 Compare October 19, 2026 18:20
// mounts every test file under `/virtual_project`. Absolute resource paths that ngtsc emits
// verbatim (e.g. `ɵɵExternalStylesFeature(["/style-A.css"])`) therefore differ only by this
// mount prefix; strip it so the comparison is root-agnostic.
return (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change definitely makes sense

o.BinaryOperator.NotIdentical,
]);

const BINARY_OPERATORS = new Map<o.BinaryOperator, string>([

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about these changes to the output printer. I like that we can reduce the hackiness of the comparison, but I don't know that we should be re-implementing TypeScript's printer here. Maybe there's a middle-ground of keeping things like stripRedundantClarifyingParens in the normalizer but not doing all of this? Or if we do all of this, borrowing the BINARY_OPERATORS from the compiler rather than duplicating them here?

@JeanMeche
JeanMeche force-pushed the refactor/ngp-printer-parity branch from 8f33588 to 6777066 Compare October 20, 2026 01:09
…gtsc TS printer

Aligns NGP's `ExpressionPrinter` (`output_ast_printer.ts`) with `ngtsc`'s TypeScript AST printer
(`ExpressionTranslatorVisitor` + `TypeScriptAstFactory`) by implementing operator-precedence-aware
parenthesization, single-line formatting for single-return `FunctionExpr` nodes without leading
comments, and `, ` separator spacing for expression lists.

Removes `stripRedundantClarifyingParens`, `transformOutsideStringLikeTokens`, Prettier re-formatting
in `compliance_spec.ts`, and the ad-hoc parenthesization/comma/factory regexes from
`ngp_emit_normalizer.ts` and `expect_emit.ts`.
@JeanMeche
JeanMeche force-pushed the refactor/ngp-printer-parity branch from 6777066 to c80226b Compare October 20, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: compiler Issues related to `ngc`, Angular's template compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants