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 receiver on calls of imported and exported functions #35877

Merged
merged 5 commits into from
Mar 3, 2021

Conversation

ajafff
Copy link
Contributor

@ajafff ajafff commented Dec 27, 2019

fixes: #35420

@rbuckton for review

@ljharb
Copy link
Contributor

ljharb commented Dec 27, 2019

I see a lot of fixture changes but none of the test cases from #35420 added - specifically, a this-sensitive exported function being both called bare, and also .called with an explicit receiver.

@ajafff
Copy link
Contributor Author

ajafff commented Dec 27, 2019

@ljharb the vast majority of the tests only verifies the correct transpilation result by comparing with the baselines. You can see from the changed baselines that imported functions are now called indirectly, which fixes the issue with the receiver.
IMO it's not really necessary to verify the runtime behavior with a test that evaluates the transpiled code. However, if you or someone else has a strong opinion on that, I'll add a test that does it.

@ljharb
Copy link
Contributor

ljharb commented Dec 27, 2019

It's certainly not up to me, but the important thing is the correct runtime semantics of the code, not the specifics of what gets output, so it seems like those tests would be the important thing :-)

@sandersn sandersn added the For Milestone Bug PRs that fix a bug with a specific milestone label Feb 1, 2020
@ljharb
Copy link
Contributor

ljharb commented Apr 29, 2020

@sandersn 3.8.1 has come and gone (#35420 is listed as in that milestone), and this important bugfix hasn't gone out yet. any update?

@sandersn
Copy link
Member

@rbuckton This is now scheduled for 4.0. Can you review this fix during the beta?

if (!isIdentifier(node.expression)) {
return node;
}
const newExpression = substituteExpressionIdentifier(node.expression);
Copy link
Member

Choose a reason for hiding this comment

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

The substitution for the identifier should be invoked by the printer, you shouldn't have to call it directly.

@ljharb
Copy link
Contributor

ljharb commented Nov 7, 2020

Ping again - i know this needs a rebase, but it’s a pretty critical bug fix.

@rbuckton rbuckton force-pushed the import-implied-receiver branch from ec2ef0b to 0bf051b Compare February 9, 2021 04:11
@rbuckton
Copy link
Member

rbuckton commented Feb 9, 2021

I've rebased this PR and made a few small updates. We may also want to consider doing the same thing for namespace exports:

namespace X {
  export function foo(this: unknown) {
    console.log(this === X);
  }
}
namespace X {
  foo(); // compiles to `X.foo()`, so would print `true`
}

@DanielRosenwasser we should discuss this emit change at the next design meeting.

@rbuckton
Copy link
Member

I've updated this to support namespace exports as well. as its essentially a bug there too and I'd like to see how this change effects compiler performance (because we call a lot of functions on the ts namespace).

@rbuckton
Copy link
Member

@typescript-bot perf test

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 10, 2021

Heya @rbuckton, I've started to run the perf test suite on this PR at b788c09. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

@rbuckton
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..35877

Metric master 35877 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 345,618k (± 0.02%) 345,624k (± 0.02%) +6k (+ 0.00%) 345,493k 345,769k
Parse Time 1.92s (± 0.40%) 1.91s (± 0.35%) -0.01s (- 0.31%) 1.90s 1.93s
Bind Time 0.82s (± 0.60%) 0.82s (± 0.41%) -0.00s (- 0.12%) 0.82s 0.83s
Check Time 4.97s (± 0.41%) 4.94s (± 0.52%) -0.04s (- 0.72%) 4.88s 4.99s
Emit Time 5.28s (± 0.97%) 5.55s (± 0.59%) +0.27s (+ 5.11%) 5.50s 5.65s
Total Time 12.99s (± 0.38%) 13.22s (± 0.39%) +0.23s (+ 1.77%) 13.14s 13.36s
Compiler-Unions - node (v10.16.3, x64)
Memory used 214,523k (± 0.06%) 215,489k (± 0.16%) +966k (+ 0.45%) 214,155k 215,876k
Parse Time 0.78s (± 0.67%) 0.77s (± 0.67%) -0.01s (- 1.03%) 0.76s 0.78s
Bind Time 0.50s (± 1.34%) 0.50s (± 0.98%) +0.01s (+ 1.41%) 0.50s 0.52s
Check Time 10.65s (± 0.40%) 10.66s (± 0.69%) +0.01s (+ 0.05%) 10.52s 10.80s
Emit Time 2.35s (± 1.67%) 2.51s (± 1.37%) +0.17s (+ 7.16%) 2.46s 2.58s
Total Time 14.27s (± 0.38%) 14.44s (± 0.64%) +0.17s (+ 1.19%) 14.27s 14.64s
Monaco - node (v10.16.3, x64)
Memory used 355,251k (± 0.02%) 355,289k (± 0.03%) +38k (+ 0.01%) 355,060k 355,589k
Parse Time 1.55s (± 0.58%) 1.55s (± 0.57%) -0.00s (- 0.06%) 1.53s 1.57s
Bind Time 0.72s (± 0.55%) 0.73s (± 1.30%) +0.01s (+ 0.83%) 0.71s 0.75s
Check Time 5.09s (± 0.57%) 5.11s (± 0.66%) +0.02s (+ 0.39%) 5.04s 5.20s
Emit Time 2.79s (± 0.64%) 2.87s (± 1.12%) +0.08s (+ 3.05%) 2.83s 2.97s
Total Time 10.15s (± 0.32%) 10.26s (± 0.41%) +0.11s (+ 1.08%) 10.19s 10.37s
TFS - node (v10.16.3, x64)
Memory used 308,114k (± 0.02%) 308,161k (± 0.01%) +47k (+ 0.02%) 308,123k 308,249k
Parse Time 1.20s (± 0.63%) 1.20s (± 0.63%) +0.00s (+ 0.08%) 1.19s 1.22s
Bind Time 0.68s (± 0.49%) 0.68s (± 0.66%) -0.00s (- 0.29%) 0.67s 0.69s
Check Time 4.60s (± 0.57%) 4.59s (± 0.63%) -0.01s (- 0.22%) 4.54s 4.65s
Emit Time 2.94s (± 0.83%) 3.01s (± 0.51%) +0.07s (+ 2.28%) 2.97s 3.04s
Total Time 9.42s (± 0.38%) 9.48s (± 0.31%) +0.05s (+ 0.58%) 9.42s 9.56s
material-ui - node (v10.16.3, x64)
Memory used 495,626k (± 0.02%) 495,544k (± 0.02%) -81k (- 0.02%) 495,311k 495,683k
Parse Time 1.98s (± 0.39%) 1.97s (± 0.53%) -0.01s (- 0.30%) 1.95s 2.00s
Bind Time 0.65s (± 0.95%) 0.65s (± 0.72%) -0.00s (- 0.15%) 0.64s 0.66s
Check Time 13.95s (± 0.92%) 13.93s (± 0.59%) -0.03s (- 0.19%) 13.77s 14.11s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 16.59s (± 0.77%) 16.55s (± 0.51%) -0.04s (- 0.22%) 16.39s 16.74s
Angular - node (v12.1.0, x64)
Memory used 323,177k (± 0.03%) 323,238k (± 0.03%) +61k (+ 0.02%) 323,024k 323,441k
Parse Time 1.90s (± 0.66%) 1.90s (± 0.87%) +0.00s (+ 0.26%) 1.86s 1.93s
Bind Time 0.80s (± 0.86%) 0.80s (± 0.60%) +0.00s (+ 0.13%) 0.79s 0.81s
Check Time 4.85s (± 0.63%) 4.87s (± 1.32%) +0.02s (+ 0.39%) 4.76s 5.10s
Emit Time 5.40s (± 0.54%) 5.75s (± 0.43%) +0.36s (+ 6.62%) 5.70s 5.81s
Total Time 12.94s (± 0.47%) 13.32s (± 0.67%) +0.38s (+ 2.95%) 13.12s 13.60s
Compiler-Unions - node (v12.1.0, x64)
Memory used 199,902k (± 0.05%) 201,074k (± 0.06%) +1,173k (+ 0.59%) 200,776k 201,288k
Parse Time 0.77s (± 0.67%) 0.77s (± 0.80%) -0.00s (- 0.26%) 0.76s 0.78s
Bind Time 0.50s (± 0.60%) 0.50s (± 0.44%) +0.00s (+ 0.60%) 0.50s 0.51s
Check Time 9.72s (± 1.02%) 9.70s (± 1.16%) -0.02s (- 0.16%) 9.55s 10.07s
Emit Time 2.34s (± 1.01%) 2.56s (± 0.96%) +0.22s (+ 9.26%) 2.51s 2.62s
Total Time 13.33s (± 0.73%) 13.54s (± 0.87%) +0.21s (+ 1.57%) 13.37s 13.93s
Monaco - node (v12.1.0, x64)
Memory used 337,476k (± 0.01%) 337,500k (± 0.02%) +25k (+ 0.01%) 337,357k 337,652k
Parse Time 1.53s (± 0.87%) 1.53s (± 0.75%) +0.00s (+ 0.20%) 1.50s 1.55s
Bind Time 0.70s (± 0.63%) 0.70s (± 0.70%) +0.00s (+ 0.28%) 0.69s 0.71s
Check Time 4.91s (± 0.48%) 4.91s (± 0.45%) 0.00s ( 0.00%) 4.85s 4.94s
Emit Time 2.86s (± 0.57%) 2.91s (± 0.67%) +0.05s (+ 1.64%) 2.87s 2.95s
Total Time 10.00s (± 0.32%) 10.06s (± 0.33%) +0.06s (+ 0.58%) 10.00s 10.13s
TFS - node (v12.1.0, x64)
Memory used 292,351k (± 0.01%) 292,332k (± 0.02%) -19k (- 0.01%) 292,224k 292,454k
Parse Time 1.22s (± 0.69%) 1.23s (± 0.50%) +0.01s (+ 0.66%) 1.21s 1.24s
Bind Time 0.65s (± 0.34%) 0.66s (± 0.88%) +0.01s (+ 0.92%) 0.65s 0.67s
Check Time 4.50s (± 0.40%) 4.51s (± 0.34%) +0.01s (+ 0.18%) 4.49s 4.55s
Emit Time 2.96s (± 0.91%) 3.02s (± 0.91%) +0.06s (+ 2.20%) 2.95s 3.09s
Total Time 9.33s (± 0.37%) 9.42s (± 0.43%) +0.09s (+ 0.92%) 9.33s 9.51s
material-ui - node (v12.1.0, x64)
Memory used 472,776k (± 0.01%) 472,809k (± 0.01%) +33k (+ 0.01%) 472,724k 472,892k
Parse Time 1.99s (± 0.51%) 2.00s (± 0.60%) +0.01s (+ 0.70%) 1.97s 2.03s
Bind Time 0.64s (± 0.35%) 0.64s (± 1.18%) +0.00s (+ 0.47%) 0.62s 0.66s
Check Time 12.49s (± 0.70%) 12.49s (± 0.72%) -0.00s (- 0.04%) 12.33s 12.72s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.12s (± 0.58%) 15.13s (± 0.59%) +0.01s (+ 0.07%) 14.98s 15.35s
Angular - node (v14.15.1, x64)
Memory used 321,828k (± 0.01%) 321,910k (± 0.01%) +82k (+ 0.03%) 321,851k 321,993k
Parse Time 1.90s (± 0.55%) 1.90s (± 0.54%) +0.00s (+ 0.05%) 1.88s 1.92s
Bind Time 0.84s (± 0.43%) 0.84s (± 0.81%) +0.00s (+ 0.12%) 0.84s 0.87s
Check Time 4.83s (± 0.38%) 4.86s (± 0.43%) +0.03s (+ 0.60%) 4.83s 4.91s
Emit Time 5.48s (± 0.77%) 5.83s (± 0.51%) +0.35s (+ 6.46%) 5.79s 5.93s
Total Time 13.05s (± 0.49%) 13.44s (± 0.39%) +0.39s (+ 2.96%) 13.35s 13.63s
Compiler-Unions - node (v14.15.1, x64)
Memory used 199,870k (± 0.38%) 200,674k (± 0.10%) +804k (+ 0.40%) 200,098k 200,928k
Parse Time 0.79s (± 0.62%) 0.79s (± 0.43%) -0.00s (- 0.13%) 0.79s 0.80s
Bind Time 0.53s (± 0.42%) 0.53s (± 0.56%) -0.00s (- 0.56%) 0.52s 0.53s
Check Time 9.68s (± 0.56%) 9.68s (± 0.81%) -0.00s (- 0.01%) 9.54s 9.93s
Emit Time 2.34s (± 1.04%) 2.54s (± 1.48%) +0.20s (+ 8.49%) 2.48s 2.63s
Total Time 13.35s (± 0.48%) 13.55s (± 0.53%) +0.20s (+ 1.48%) 13.39s 13.76s
Monaco - node (v14.15.1, x64)
Memory used 336,849k (± 0.01%) 336,929k (± 0.00%) +80k (+ 0.02%) 336,901k 336,961k
Parse Time 1.55s (± 0.58%) 1.55s (± 0.64%) +0.00s (+ 0.13%) 1.53s 1.57s
Bind Time 0.73s (± 0.71%) 0.73s (± 0.64%) +0.00s (+ 0.14%) 0.72s 0.74s
Check Time 4.85s (± 0.61%) 4.85s (± 0.48%) -0.00s (- 0.08%) 4.80s 4.91s
Emit Time 2.91s (± 0.41%) 3.00s (± 0.86%) +0.08s (+ 2.85%) 2.96s 3.08s
Total Time 10.05s (± 0.39%) 10.12s (± 0.45%) +0.08s (+ 0.78%) 10.06s 10.28s
TFS - node (v14.15.1, x64)
Memory used 291,545k (± 0.00%) 291,547k (± 0.01%) +2k (+ 0.00%) 291,518k 291,588k
Parse Time 1.24s (± 0.99%) 1.24s (± 1.23%) +0.00s (+ 0.24%) 1.22s 1.29s
Bind Time 0.69s (± 0.64%) 0.69s (± 0.84%) +0.00s (+ 0.14%) 0.68s 0.71s
Check Time 4.50s (± 0.62%) 4.50s (± 0.41%) +0.01s (+ 0.16%) 4.45s 4.54s
Emit Time 3.03s (± 0.46%) 3.13s (± 0.70%) +0.09s (+ 3.13%) 3.08s 3.18s
Total Time 9.46s (± 0.30%) 9.57s (± 0.37%) +0.11s (+ 1.17%) 9.51s 9.66s
material-ui - node (v14.15.1, x64)
Memory used 471,401k (± 0.06%) 471,503k (± 0.01%) +102k (+ 0.02%) 471,437k 471,554k
Parse Time 2.06s (± 0.78%) 2.05s (± 0.71%) -0.00s (- 0.19%) 2.02s 2.08s
Bind Time 0.70s (± 0.74%) 0.70s (± 0.64%) -0.00s (- 0.43%) 0.69s 0.71s
Check Time 12.63s (± 0.83%) 12.55s (± 1.53%) -0.07s (- 0.59%) 12.38s 13.31s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.38s (± 0.75%) 15.30s (± 1.31%) -0.08s (- 0.54%) 15.11s 16.09s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-198-generic
Architecturex64
Available Memory16 GB
Available Memory7 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v14.15.1, x64)
Benchmark Name Iterations
Current 35877 10
Baseline master 10

@rbuckton
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 12, 2021

Heya @rbuckton, I've started to run the tarball bundle task on this PR at b788c09. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 12, 2021

Hey @rbuckton, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/95810/artifacts?artifactName=tgz&fileId=F8AD257B669FDE703D7FF39DE9A54CE25327D7236435DF39341C2F15BD09C00802&fileName=/typescript-4.3.0-insiders.20210212.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;

@rbuckton
Copy link
Member

rbuckton commented Mar 3, 2021

Per discussion with @RyanCavanaugh today, I'm going to revert the change for namespaces for the time being.

@rbuckton rbuckton force-pushed the import-implied-receiver branch from b788c09 to 80ac673 Compare March 3, 2021 01:59
# Conflicts:
#	tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
@rbuckton
Copy link
Member

rbuckton commented Mar 3, 2021

Hmm. build is failing for a unit test that doesn't exist anymore...

Ah, that's a typo in the externalModules.ts test.

@rbuckton
Copy link
Member

rbuckton commented May 7, 2021

It looks like we will need to revert this change until TS 4.4 while we investigate the significant performance regression this causes during emit. In the worst case, we may need to land this behind a flag to opt-in to the change, though ideally I can find a mitigation for the performance regression so that we can land this without a flag.

@ljharb
Copy link
Contributor

ljharb commented May 7, 2021

Reverting this seems like it will restore the active breakage on a number of my shims like Promise.allSettled, where the module.exports function explicitly relies on having an undefined receiver.

Why does a performance regression matter when compared to runtime breakage?

@ljharb
Copy link
Contributor

ljharb commented Jun 10, 2021

@rbuckton ping, TS is severely broken without this fix; any update on restoring it?

@DanielRosenwasser
Copy link
Member

We re-re-discussed this at #44555.

We've always tried to balance reasonable/canonical-looking emit and general UX with exact semantics of the spec. We're not ready to sacrifice that and also impose an emit overhead on everyone, especially when performance is something we're really working to improve. If we can find some optimizations that make this "free-ish", we'd feel better about this feature; otherwise, we'll need to put it behind a flag (like --downlevelIteration, --useDefinedForClassFields, etc.).

Why does a performance regression matter when compared to runtime breakage?

The bigger risk here is actually imposing runtime breakage on existing users who accidentally came to rely on the existing behavior. Given that, the safer thing might actually be to put it behind a flag.

@ljharb
Copy link
Contributor

ljharb commented Jun 11, 2021

@DanielRosenwasser so you’re worried about users who expect that, defying the way it works everywhere else in the JS exosystem, an exported function’s receiver will be the module namespace object when called as a bare function? I’d love to understand what code is relying on this behavior.

@RyanCavanaugh
Copy link
Member

so you’re worried about users who expect that, defying the way it works everywhere else in the JS exosystem

Yes. Improved spec compliance has caused problems before, e.g. when we made exports immutable/nonenumerable (jasmine/jasmine#1817, #38568).

@ljharb
Copy link
Contributor

ljharb commented Jun 14, 2021

Alright - can it at least be landed behind a flag, so i can tell users how to unbreak their applications?

@RyanCavanaugh
Copy link
Member

We're definitely going to figure something out, just trying to work out what exactly that is

@rbuckton
Copy link
Member

We were able to re-land this in #44624 in a way that does not significantly impact emit performance.

@ljharb
Copy link
Contributor

ljharb commented Jun 22, 2021

That's amazing, great to hear!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Milestone Bug PRs that fix a bug with a specific milestone
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Functions wrapped in __importDefault with allowSyntheticDefaultImports emit incorrect function calls
7 participants