Skip to content

fix(ivy): ngcc should not emit TypeScript syntax - #27051

Closed
JoostK wants to merge 1 commit into
angular:masterfrom
JoostK:ngcc-js-output
Closed

JoostK wants to merge 1 commit into
angular:masterfrom
JoostK:ngcc-js-output

Conversation

@JoostK

@JoostK JoostK commented Nov 11, 2018

Copy link
Copy Markdown
Member

Previously, ngcc used ngtsc's logic to transform the Angular AST
to a TypeScript AST and then leverages TypeScript's node printer to
obtain the source text to insert. This turns out to be a problem when
specific TypeScript syntax is represented in the AST; the printer cannot
be configured to output only JavaScript syntax.

A full-blown TypeScript emit of a complete ts.SourceFile would be
required to be able to emit JS and possibly downlevel into a lower
language target, which is not an option for ngcc as it currently
operates on partial ASTs, not full source files.

Instead, the Angular AST itself is used to emit source files, using the
emitter logic that is also used in JIT compilations. As the Angular AST
produced by ngtsc may contain literal TypeScript nodes inside of
WrappedNodeExpr, a TypeScript printer is still used to obtain source
text for such nodes (assuming no TypeScript specific syntax is present
within that node's subtree).

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?

ngcc may output TypeScript specific syntax into JavaScript bundles, which fail to be parsed.

What is the new behavior?

ngcc uses existing emitter logic that operates on Angular AST to produce JavaScript code instead of TypeScript.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@alxhub Can you comment on my assumption that we can safely print WrappedNodeExpr using TypeScript's printing logic, as doing so still has a risk of producing TS specific syntax.

@petebacondarwin

Copy link
Copy Markdown
Contributor

@alxhub Can you comment on my assumption that we can safely print WrappedNodeExpr using TypeScript's printing logic, as doing so still has a risk of producing TS specific syntax.

I am pretty confident that for ngcc, all of these wrapped nodes will have come from JS files, so it seems likely that they are already JS. Right?

@petebacondarwin

Copy link
Copy Markdown
Contributor

Generally looks like a good idea!

@petebacondarwin petebacondarwin added action: review The PR is still awaiting reviews from at least one requested reviewer effort1: hours freq2: medium comp: ivy risk: medium labels Nov 11, 2018
@ngbot ngbot Bot added this to the needsTriage milestone Nov 11, 2018
@petebacondarwin petebacondarwin modified the milestones: needsTriage, Ivy Nov 11, 2018
@ngbot ngbot Bot modified the milestones: Ivy, needsTriage Nov 11, 2018
@ngbot ngbot Bot modified the milestones: needsTriage, Backlog Nov 11, 2018
@petebacondarwin petebacondarwin modified the milestones: Backlog, Ivy Nov 11, 2018
@JoostK
JoostK force-pushed the ngcc-js-output branch 2 times, most recently from 8c97aa2 to 8cc985f Compare November 11, 2018 23:44

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.

How do we know what name is defined? Should we not check name for the whole function body?

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.

Was the previous printer producing a fat arrow here or something?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nope, it was only the non-null assertion in the template (person!.name) that tripped stuff up. It's actually surprising that the TypeScript printer has worked so well until that tiny syntactical difference.

@petebacondarwin petebacondarwin added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Nov 12, 2018
@JoostK
JoostK force-pushed the ngcc-js-output branch 5 times, most recently from 95abaaf to 78e3da4 Compare November 26, 2018 20:25
@JoostK

JoostK commented Nov 26, 2018

Copy link
Copy Markdown
Member Author

@petebacondarwin @alxhub After a rebase this is now green again, should be good to go. Let me know if we do want to elide the ! in ngtsc directly, if so I'll update the PR accordingly.

@gkalpak gkalpak mentioned this pull request Dec 7, 2018
11 of 13 tasks
@JoostK
JoostK force-pushed the ngcc-js-output branch 2 times, most recently from 8b2fc25 to 518b043 Compare December 10, 2018 18:24
@JoostK JoostK changed the title fix(ivy): ngcc should render JavaScript instead of TypeScript fix(ivy): ngcc should not emit TypeScript syntax Dec 10, 2018
@petebacondarwin petebacondarwin added action: review The PR is still awaiting reviews from at least one requested reviewer and removed action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews labels Dec 12, 2018

@petebacondarwin petebacondarwin 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.

This fix looks good to me. It needs to have an ngtsc test too IMO. I am going to add one.
Then leave it to @alxhub to do final approval.

@petebacondarwin
petebacondarwin dismissed their stale review December 12, 2018 13:51

I realised that ngtsc outputs its AST through a JS renderer so that the non-JS AST nodes are removed, which makes a test inside ngtsc_spec.ts not possible.

@petebacondarwin petebacondarwin 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.

LGTM! @alxhub over to you. I have rebased on master, just to be sure!

@JoostK
JoostK force-pushed the ngcc-js-output branch 2 times, most recently from 518b043 to aebacd3 Compare December 12, 2018 19:53
If a template contains specific TypeScript syntax, such as a non-null
assertion, the code that is emitted from ngcc into a JavaScript bundle
should not retain such syntax as it is invalid in JS.

A full-blown TypeScript emit of a complete ts.SourceFile would be
required to be able to emit JS and possibly downlevel into a lower
language target, which is not an option for ngcc as it currently
operates on partial ASTs, not full source files.

Instead, ngtsc no longer produces TypeScript specific syntax in the first
place, such that TypeScript print logic will only generate JS code.
@alxhub alxhub added action: merge The PR is ready for merge by the caretaker target: major This PR is targeted for the next major release and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Dec 13, 2018
@alxhub

alxhub commented Dec 13, 2018

Copy link
Copy Markdown
Member

@mhevery mhevery closed this in 023bd31 Dec 14, 2018
@JoostK
JoostK deleted the ngcc-js-output branch December 15, 2018 16:23
@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 Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker cla: yes effort1: hours freq2: medium risk: medium target: major This PR is targeted for the next major release type: bug/fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants