Skip to content

fix(emit): (v) => ({value: v}).value is printed as invalid (v) =>{value:v}.value #510

Description

@Brooooooklyn

When an arrow body starts with a parenthesized object literal but isn't only that object (member access, call, and so on), the emitter drops the parentheses. The output is invalid JS, or JS with a different meaning.

Repro (input transform)

import {Directive, Input} from '@angular/core';
@Directive({selector: '[d]'})
export class D {
  @Input({transform: (v: any) => ({value: v}).value}) a: any;
}

Repro (provider factory)

import {Component} from '@angular/core';
@Component({selector: 'c', template: '', providers: [{provide: 'T', useFactory: () => ({a: 1}).a}]})
export class C {}

OXC (main and #504 tip)

inputs:{a:[2,"a","a",(v) =>{value:v}.value]}
// setClassMetadata
args:[{transform:(v) =>{value:v}.value}]
i0.ɵɵProvidersFeature([{provide:"T",useFactory:() =>{a:1}.a}])

ngtsc 22.1.7

inputs: { a: [2, "a", "a", (v) => ({ value: v }).value] }
i0.ɵɵProvidersFeature([{ provide: 'T', useFactory: () => ({ a: 1 }).a }])

Where

crates/oxc_angular_compiler/src/output/emitter.rs (main ~L742 and ~L766):

  • OutputExpression::Parenthesized prints only its inner expression, without the parentheses.
  • The ArrowFunction arm adds (...) only when the whole body is an object literal (LiteralMap, after unwrapping one Parenthesized). A body like ReadProp(Parenthesized(LiteralMap)) starts with { but gets no parentheses.

Related: #43 (closed) fixed the plain () => ({...}) case. Open PR #498 extends the same check to raw-source objects but still only checks the whole body, so it doesn't fix this.

On main?

Yes.

Direction

Add parentheses when the leftmost token of the body would be {: walk receivers of member access, calls, binary operators and so on. Or have Parenthesized keep its parentheses whenever the inner expression is an object literal.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions