Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compiler-cli): interpret string concat calls #44167

Closed
wants to merge 1 commit into from

Conversation

crisbeto
Copy link
Member

These changes add support for interpreting String.prototype.concat calls. We need to support it, because in TypeScript 4.5 string template expressions are transpiled to concat calls, rather than string concatenations. See microsoft/TypeScript#45304.

These changes add support for interpreting `String.prototype.concat` calls. We need to support it, because in TypeScript 4.5 string template expressions are transpiled to `concat` calls, rather than string concatenations. See microsoft/TypeScript#45304.
@google-cla google-cla bot added the cla: yes label Nov 14, 2021
@crisbeto crisbeto marked this pull request as ready for review November 14, 2021 09:03
@pullapprove pullapprove bot requested a review from alxhub November 14, 2021 09:03
@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer area: compiler Issues related to `ngc`, Angular's template compiler target: patch This PR is targeted for the next patch release labels Nov 14, 2021
@ngbot ngbot bot modified the milestone: Backlog Nov 14, 2021
Copy link
Member

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

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

Nice addition @crisbeto.

I "think" that this change to TS will not break $localize processing in @angular/localize because even in ES5 mode a tagged template handler will not be a simple string, but instead will continue to be a function call with the "message parts" added as parameters.

That being said, we should consider changing the output of $localize processing to follow this same approach (rather than using +) to get the same level of spec compliance. For context the following localized message $localize `hello ${name}!`; will be translated to, say, "bonjour " + name + "!"; - and I guess it should be translated to "bonjour".concat(value).concat("!");.

@@ -533,6 +533,17 @@ runInEachFileSystem(() => {
.toBe('a.test.b');
});

it('string `concat` function works', () => {
expect(evaluate(`const a = '12', b = '34';`, 'a[\'concat\'](b)')).toBe('1234');
Copy link
Member

Choose a reason for hiding this comment

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

All the tests here appear to test the element access form: a['concat'].
I assume that the changes also support property access form a.concat too? If so, can we add tests to prove it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that these tests don't have any typings so using the .concat access throws a type error. All the other tests use the same trick.

@crisbeto
Copy link
Member Author

This change wasn't prompted by $localize, but rather because of an ngcc test that has a component template with interpolations: https://github.com/angular/angular/blob/master/packages/compiler-cli/ngcc/test/integration/ngcc_spec.ts#L539.

I caught it in my PR to add support for TS 4.5: #44164

@JoostK
Copy link
Member

JoostK commented Nov 15, 2021

Maybe we should consider changing the ngcc integration tests to not rely on the workspace TS version, as ngcc will not have to deal with TS >=4.4 emit output in real life. This isn't the first time where we need to adapt ngtsc to support ngcc and I'd like to reduce the complexity/effort around TS updates going forward.

@petebacondarwin
Copy link
Member

Maybe we should consider changing the ngcc integration tests to not rely on the workspace TS version, as ngcc will not have to deal with TS >=4.4 emit output in real life. This isn't the first time where we need to adapt ngtsc to support ngcc and I'd like to reduce the complexity/effort around TS updates going forward.

I think in this case, this is actually a valuable contribution to the compiler generally, expanding the syntaxes understood by our static evaluation of TS.

@crisbeto
Copy link
Member Author

crisbeto commented Nov 15, 2021

The test revealed a legitimate issue though. It meant that something like this would throw a compiler error where it previously didn't:

const name = '...';

@Component({
  template: `Hello ${name}`
})

@petebacondarwin
Copy link
Member

But only if you were targeting es5 I think. And even then, I think the Angular compilation happens before the downleveling.

@JoostK
Copy link
Member

JoostK commented Nov 15, 2021

That's indeed only relevant when ngtsc is processing JS code, which is only the case with ngcc. Regular compilations perform analysis using the original TS source code and see the template literal as written by the user.

With this commit, the user would be allowed to write:

const name = '...';

@Component({
  template: 'Hello '.concat(name),
})

TBH I'm not convinced that we should support this (but we already do support Array.prototype.concat and Array.prototype.slice which were added to support ngcc, but they're also available to regular ngtsc compiles)

@crisbeto
Copy link
Member Author

IMO we still need to support cases like this as long as ngcc exists in the codebase.

@petebacondarwin
Copy link
Member

petebacondarwin commented Nov 15, 2021

IMO we still need to support cases like this as long as ngcc exists in the codebase.

That is only necessary if people are able to build ViewEngine formatted libraries using TS 4.5, which is not the case, unless we updated 12.2.x to support TS 4.5.

But I do think it is not a bad idea to support this construct. It would also allow us to do things like:

const prefix = 'moo';

@Component({selector: previx.concat('-my-comp'), ...})
...

(I think...)

@alxhub
Copy link
Member

alxhub commented Nov 18, 2021

I agree with @JoostK's assessment that this is not strictly necessary, because there is no way that ngcc could encounter a package in the wild that's built with TS 4.5, since such a package would need to be built with Angular 12 or lower, and that doesn't support TS 4.5.

That said, supporting this is easy, and it unblocks the 4.5 update work while we think about changing how we generate ngcc's test code (which we should also do).

@crisbeto crisbeto added action: merge The PR is ready for merge by the caretaker action: presubmit The PR is in need of a google3 presubmit and removed action: review The PR is still awaiting reviews from at least one requested reviewer action: presubmit The PR is in need of a google3 presubmit labels Nov 18, 2021
@jessicajaniuk
Copy link
Contributor

This PR was merged into the repository by commit 48ca7dc.

jessicajaniuk pushed a commit that referenced this pull request Nov 19, 2021
These changes add support for interpreting `String.prototype.concat` calls. We need to support it, because in TypeScript 4.5 string template expressions are transpiled to `concat` calls, rather than string concatenations. See microsoft/TypeScript#45304.

PR Close #44167
@angular-automatic-lock-bot
Copy link

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 Dec 20, 2021
dimakuba pushed a commit to dimakuba/angular that referenced this pull request Dec 28, 2021
These changes add support for interpreting `String.prototype.concat` calls. We need to support it, because in TypeScript 4.5 string template expressions are transpiled to `concat` calls, rather than string concatenations. See microsoft/TypeScript#45304.

PR Close angular#44167
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 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.

None yet

5 participants