Skip to content

fix(compiler): Expression converter typo - #37361

Closed
ajitsinghkaler wants to merge 1 commit into
angular:masterfrom
ajitsinghkaler:ve-typo
Closed

ajitsinghkaler wants to merge 1 commit into
angular:masterfrom
ajitsinghkaler:ve-typo

Conversation

@ajitsinghkaler

Copy link
Copy Markdown
Contributor

In expression converter for literal values of null, undefined, true, or false type interference was to be done but it was not done for value false. Added false also to the check.

Fixes #21233

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

a typo
Issue Number: #21233

What is the new behavior?

typo removed

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

In expression converter for literal values of null, undefined, true, or false type interference was to be done but it was not done for value false. Added false also to the check.

Fixes angular#21233
@pullapprove
pullapprove Bot requested a review from AndrewKushnir May 30, 2020 13:32
@pkozlowski-opensource

Copy link
Copy Markdown
Member

We definitively need an additional test (one that would fail without the code change and starts passing with the code change)

@ajitsinghkaler

ajitsinghkaler commented May 30, 2020 •

Copy link
Copy Markdown
Contributor Author

@pkozlowski-opensource I don't see any unit tests added for the method visitLiteralPrimitive() do I write an integration test

@ngbot ngbot Bot added this to the needsTriage milestone May 30, 2020
@petebacondarwin petebacondarwin added area: compiler Issues related to `ngc`, Angular's template compiler and removed comp: docs/api labels May 30, 2020
@petebacondarwin

Copy link
Copy Markdown
Contributor

Ideally there should be a test of some kind to demonstrate this.

@AndrewKushnir AndrewKushnir added engine: ve action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release labels May 30, 2020
@AndrewKushnir
AndrewKushnir requested a review from alxhub May 30, 2020 21:31

@AndrewKushnir AndrewKushnir left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ajitsinghkaler, thanks for creating this PR. As Pawel and Pete mentioned, it'd be great to have a test to verify this change. The code was originally introduced in
82bcd83 and there are some tests there, so may be you can use one of them as a base for the new test.

I'm also adding @alxhub as a reviewer as he may have additional context on this.

Thank you.

@ajitsinghkaler
ajitsinghkaler marked this pull request as draft June 15, 2020 16:22
@ajitsinghkaler

Copy link
Copy Markdown
Contributor Author

@AndrewKushnir I tried to write the test but could not understand how to write a test for this can you please help me.

@AndrewKushnir

Copy link
Copy Markdown
Contributor

Hi @ajitsinghkaler, I tried to reuse one of the tests from 82bcd83 and was able to trigger the codepath updated in this PR, but I was unable to come up with a case when a test would fail with current state of the master branch and will pass after the change in this PR (which is needed to validate that everything works as needed). May be @petebacondarwin or @alxhub have additional thoughts/ideas. Thank you.

@petebacondarwin

petebacondarwin commented Jun 24, 2020 •

Copy link
Copy Markdown
Contributor

I think the reason we can't make a failing test is that our typing checks tend not to distinguish between null, undefined and false (or even 0!!).

See

this.type = type || null;

@JoostK

JoostK commented Jun 24, 2020 •

Copy link
Copy Markdown
Member

@petebacondarwin but the type would be o.INFERRED_TYPE. I think a test that might currently fail would be the following scenario:

<button [id]="computeId(false)"></button>
export class MyCmp {
  doSomething(param: number): string { return ''; }
}

One would expect this not to typecheck, als literal false should be inferred to boolean instead of just any.

Note that since Ivy, any type information on the output AST is not used at all.

@petebacondarwin

petebacondarwin commented Jun 24, 2020 •

Copy link
Copy Markdown
Contributor

I created a template that looks like this:

<div *myIf="person.display != false"> {{person.name}} </div>

where person.display is of type boolean.

The rendered type check block is:

function _View_MainComp_1_0():void {
  var _any:any = (null as any);
  const currVal_0:any = (_decl0_0.person.display != false);
  currVal_0;
}

I believe that because false has been assigned null for its type, it gets cast to a "dynamic" type, which then causes the result of the comparison to also become "dynamic", hence the currVal_0:any.

@petebacondarwin

Copy link
Copy Markdown
Contributor

I'll have a play with a function call as in your suggestion @JoostK .

@petebacondarwin

Copy link
Copy Markdown
Contributor

So a template like:

<button [id]="computeId(false)"></button>

doesn't trigger the visitLiteralPrimitive() method here at all!

@JoostK

JoostK commented Jun 24, 2020

Copy link
Copy Markdown
Member

After looking into it some more, I can't think of a way to reproduce a bug here.

The type is only relevant if a temporary has to be introduced, which only happens for the LHS of safe navigation operators. Therefore, the literal itself is never assigned into a temporary. In the TS emitter, the type is only used when the literal is null:

visitLiteralExpr(ast: o.LiteralExpr, ctx: EmitterVisitorContext): any {
const value = ast.value;
if (value == null && ast.type != o.INFERRED_TYPE) {
ctx.print(ast, `(${value} as any)`);
return null;
}
return super.visitLiteralExpr(ast, ctx);
}

For the boolean case, the literal will be emitted as is. Therefore, the literal type is retained.

Alas, I don't think the code with the bug has a real purpose.

@ajitsinghkaler

Copy link
Copy Markdown
Contributor Author

@JoostK so should we remove this code

@petebacondarwin

Copy link
Copy Markdown
Contributor

I think that despite no test (and possibly despite this code being used!!) we should land this change since clearly the current code is not correct.

@jelbourn

jelbourn commented Apr 6, 2021

Copy link
Copy Markdown
Contributor

Closing this since it's been several months- feel free to open a new PR that either cleans up the unnecessary code or adds tests for a behavior change.

@angular-automatic-lock-bot

Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators May 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: compiler Issues related to `ngc`, Angular's template compiler cla: yes target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expression converter typo

8 participants