Skip to content

Reparse top level 'await' in modules #39084

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

Merged
merged 3 commits into from
Jun 19, 2020
Merged

Reparse top level 'await' in modules #39084

merged 3 commits into from
Jun 19, 2020

Conversation

rbuckton
Copy link
Member

This adds support to the parser to re-parse expressions containing await as an identifier after we have parsed a source file and determined it to be a module. Cases covered include:

  • Parses correctly:
    • await (x)
    • await <T>(x)
    • await ``
    • await <T>``
    • await[x]
  • Parses with appropriate errors:
    • await () - Expression expected at )
    • await (x, ) - Expression expected at )
    • await <T, U>(x) - > expected at ,
    • await .x - Expression expected at .
    • await ?.x - Expression expected at ?.
    • await ?.[x] - Expression expected at ?.
    • const await = ... - Identifier expected at await
    • And various others

This depends on #35282

Fixes #36817

@rbuckton
Copy link
Member Author

The relevant commits start at 8ab882a

@rbuckton rbuckton marked this pull request as ready for review June 17, 2020 00:13
Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

Looks good, just some small questions/comments.

Also: are there any tests for the decorators, eg, @await and @(await whatever) and/or @await(whatever)?


// If we parsed this as an external module, it may contain top-level await
if (isExternalModule(sourceFile) && sourceFile.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) {
sourceFile = reparseTopLevelAwait(sourceFile);
Copy link
Member

Choose a reason for hiding this comment

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

Hm. Should we do something smarter when we're doing an incremental parse, like only visiting and reparsing the changed subtree?

Copy link
Member Author

Choose a reason for hiding this comment

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

The biggest issue with incremental parse is that it depends in part on differences in the context flags, and whether the top-level is an Await context is dependent on whether we treat it as a module. What happens when the changed subtree includes a new export {} that turns the file into a module? What I might do is hold onto a pointer for the non-reparsed source file to pass to incremental parse, and then just handle reparse individually as needed. We might not get as much node reuse inside of expressions, but incremental parse node reuse only applies to a limited set of list contexts (statements, class members, switch clauses, etc.) and is ignored at the expression level.

if (node && node.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) {
if (isExpression(node)) {
return speculationHelper(() => {
scanner.setTextPos(node.pos);
Copy link
Member

Choose a reason for hiding this comment

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

Would using initializeState and passing in a syntax cursor here allow us to reuse the initially parsed nodes where possible, even in the case of a partial reparse? (Reparse due to context invalidation and incremental reparsing I would think seem similar)

Copy link
Member Author

Choose a reason for hiding this comment

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

Possibly. I'm on the fence as to whether I wanted to set original pointers for these nodes. I need to add some incremental parse test cases.

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 considered using incremental parse, but it doesn't apply at the expression level, only at certain list context levels (see #39084 (comment)). I might have been able to leverage it by reparsing the statement itself, but some of the necessary incremental parse machinery isn't currently accessible from within Parser, and would be fairly complex to wire up properly.

@rbuckton
Copy link
Member Author

@weswigham would you mind giving this one more look over now that I've added some additional tests and a few changes?

@rbuckton
Copy link
Member Author

@typescript-bot perf test
@typescript-bot run dt
@typescript-bot test this
@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 18, 2020

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 18, 2020

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

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 18, 2020

Heya @rbuckton, I've started to run the parallelized Definitely Typed test suite on this PR at 097972f. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 18, 2020

Heya @rbuckton, I've started to run the parallelized community code test suite on this PR at 097972f. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - master..39084

Metric master 39084 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 340,235k (± 0.02%) 339,747k (± 0.03%) -488k (- 0.14%) 339,556k 339,990k
Parse Time 1.97s (± 0.57%) 1.99s (± 0.59%) +0.01s (+ 0.71%) 1.96s 2.01s
Bind Time 0.79s (± 1.17%) 0.80s (± 1.00%) +0.01s (+ 0.76%) 0.78s 0.81s
Check Time 4.71s (± 0.46%) 4.71s (± 0.53%) +0.01s (+ 0.11%) 4.65s 4.78s
Emit Time 5.20s (± 0.66%) 5.21s (± 0.82%) +0.01s (+ 0.21%) 5.11s 5.29s
Total Time 12.67s (± 0.39%) 12.70s (± 0.53%) +0.03s (+ 0.26%) 12.54s 12.81s
Monaco - node (v10.16.3, x64)
Memory used 338,721k (± 0.02%) 338,855k (± 0.02%) +134k (+ 0.04%) 338,688k 339,023k
Parse Time 1.55s (± 0.64%) 1.58s (± 0.61%) +0.02s (+ 1.42%) 1.56s 1.59s
Bind Time 0.69s (± 0.43%) 0.70s (± 0.64%) +0.01s (+ 1.45%) 0.69s 0.71s
Check Time 4.84s (± 0.60%) 4.85s (± 0.42%) +0.01s (+ 0.12%) 4.80s 4.89s
Emit Time 2.74s (± 0.69%) 2.76s (± 1.20%) +0.02s (+ 0.91%) 2.71s 2.86s
Total Time 9.82s (± 0.41%) 9.88s (± 0.41%) +0.06s (+ 0.64%) 9.78s 9.98s
TFS - node (v10.16.3, x64)
Memory used 301,524k (± 0.03%) 301,490k (± 0.02%) -34k (- 0.01%) 301,308k 301,622k
Parse Time 1.22s (± 0.83%) 1.22s (± 0.82%) +0.00s (+ 0.16%) 1.20s 1.24s
Bind Time 0.64s (± 1.09%) 0.65s (± 0.90%) +0.01s (+ 0.94%) 0.63s 0.66s
Check Time 4.35s (± 0.47%) 4.35s (± 0.46%) +0.00s (+ 0.02%) 4.32s 4.41s
Emit Time 2.87s (± 1.30%) 2.86s (± 1.66%) -0.02s (- 0.56%) 2.75s 2.95s
Total Time 9.08s (± 0.53%) 9.07s (± 0.63%) -0.01s (- 0.09%) 8.98s 9.22s
material-ui - node (v10.16.3, x64)
Memory used 459,101k (± 0.02%) 458,807k (± 0.01%) -293k (- 0.06%) 458,707k 458,918k
Parse Time 2.02s (± 0.62%) 2.03s (± 0.66%) +0.01s (+ 0.30%) 2.00s 2.07s
Bind Time 0.64s (± 0.75%) 0.64s (± 0.87%) +0.01s (+ 0.78%) 0.63s 0.66s
Check Time 12.89s (± 0.79%) 12.85s (± 0.60%) -0.03s (- 0.26%) 12.69s 13.08s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.55s (± 0.67%) 15.52s (± 0.55%) -0.03s (- 0.17%) 15.34s 15.77s
Angular - node (v12.1.0, x64)
Memory used 317,424k (± 0.07%) 317,225k (± 0.02%) -198k (- 0.06%) 317,111k 317,372k
Parse Time 1.95s (± 0.76%) 1.96s (± 0.79%) +0.00s (+ 0.20%) 1.94s 2.00s
Bind Time 0.78s (± 0.60%) 0.78s (± 1.02%) +0.00s (+ 0.26%) 0.77s 0.81s
Check Time 4.59s (± 0.61%) 4.58s (± 0.40%) -0.01s (- 0.22%) 4.54s 4.62s
Emit Time 5.33s (± 0.69%) 5.32s (± 0.62%) -0.01s (- 0.17%) 5.26s 5.40s
Total Time 12.66s (± 0.46%) 12.64s (± 0.37%) -0.02s (- 0.13%) 12.54s 12.78s
Monaco - node (v12.1.0, x64)
Memory used 321,270k (± 0.02%) 321,278k (± 0.04%) +8k (+ 0.00%) 320,723k 321,456k
Parse Time 1.52s (± 0.99%) 1.54s (± 0.65%) +0.02s (+ 1.38%) 1.52s 1.56s
Bind Time 0.67s (± 0.60%) 0.67s (± 1.31%) +0.00s (+ 0.60%) 0.65s 0.69s
Check Time 4.62s (± 0.45%) 4.67s (± 0.59%) +0.05s (+ 0.97%) 4.63s 4.75s
Emit Time 2.79s (± 0.56%) 2.82s (± 0.66%) +0.03s (+ 1.26%) 2.79s 2.87s
Total Time 9.60s (± 0.42%) 9.71s (± 0.32%) +0.11s (+ 1.15%) 9.65s 9.77s
TFS - node (v12.1.0, x64)
Memory used 285,946k (± 0.02%) 286,033k (± 0.02%) +87k (+ 0.03%) 285,899k 286,194k
Parse Time 1.23s (± 1.04%) 1.23s (± 0.45%) +0.00s (+ 0.33%) 1.22s 1.24s
Bind Time 0.62s (± 0.72%) 0.62s (± 0.72%) +0.00s (+ 0.00%) 0.61s 0.63s
Check Time 4.26s (± 0.78%) 4.26s (± 0.45%) +0.00s (+ 0.09%) 4.22s 4.32s
Emit Time 2.91s (± 0.87%) 2.92s (± 0.71%) +0.02s (+ 0.65%) 2.87s 2.96s
Total Time 9.01s (± 0.53%) 9.04s (± 0.19%) +0.03s (+ 0.33%) 8.99s 9.07s
material-ui - node (v12.1.0, x64)
Memory used 437,670k (± 0.01%) 437,218k (± 0.08%) -452k (- 0.10%) 436,282k 437,616k
Parse Time 2.01s (± 0.42%) 2.01s (± 0.41%) +0.00s (+ 0.20%) 2.00s 2.03s
Bind Time 0.63s (± 1.07%) 0.63s (± 0.83%) -0.01s (- 0.79%) 0.62s 0.64s
Check Time 11.58s (± 1.02%) 11.63s (± 0.97%) +0.04s (+ 0.37%) 11.35s 11.95s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 14.23s (± 0.88%) 14.27s (± 0.80%) +0.04s (+ 0.30%) 13.97s 14.58s
Angular - node (v8.9.0, x64)
Memory used 336,574k (± 0.02%) 336,341k (± 0.02%) -233k (- 0.07%) 336,156k 336,524k
Parse Time 2.49s (± 0.42%) 2.50s (± 0.27%) +0.01s (+ 0.32%) 2.48s 2.51s
Bind Time 0.84s (± 1.07%) 0.83s (± 1.21%) -0.01s (- 1.08%) 0.81s 0.85s
Check Time 5.32s (± 0.48%) 5.36s (± 0.53%) +0.05s (+ 0.87%) 5.29s 5.41s
Emit Time 5.87s (± 1.11%) 5.90s (± 1.86%) +0.03s (+ 0.46%) 5.66s 6.11s
Total Time 14.52s (± 0.54%) 14.59s (± 0.79%) +0.07s (+ 0.50%) 14.35s 14.87s
Monaco - node (v8.9.0, x64)
Memory used 340,078k (± 0.01%) 340,133k (± 0.01%) +54k (+ 0.02%) 340,034k 340,218k
Parse Time 1.85s (± 0.35%) 1.87s (± 0.45%) +0.02s (+ 0.92%) 1.85s 1.89s
Bind Time 0.86s (± 0.52%) 0.87s (± 0.46%) +0.01s (+ 0.81%) 0.86s 0.88s
Check Time 5.32s (± 0.66%) 5.37s (± 0.61%) +0.04s (+ 0.81%) 5.30s 5.45s
Emit Time 3.21s (± 0.58%) 3.22s (± 0.58%) +0.02s (+ 0.50%) 3.18s 3.27s
Total Time 11.25s (± 0.46%) 11.33s (± 0.43%) +0.08s (+ 0.73%) 11.24s 11.47s
TFS - node (v8.9.0, x64)
Memory used 303,205k (± 0.02%) 303,222k (± 0.01%) +17k (+ 0.01%) 303,138k 303,302k
Parse Time 1.53s (± 0.24%) 1.53s (± 0.44%) -0.00s (- 0.13%) 1.52s 1.55s
Bind Time 0.65s (± 0.77%) 0.65s (± 0.91%) +0.01s (+ 1.40%) 0.64s 0.66s
Check Time 4.93s (± 1.75%) 4.99s (± 1.34%) +0.06s (+ 1.16%) 4.88s 5.11s
Emit Time 3.07s (± 2.38%) 3.07s (± 2.87%) +0.00s (+ 0.03%) 2.89s 3.19s
Total Time 10.19s (± 0.42%) 10.25s (± 0.44%) +0.06s (+ 0.63%) 10.15s 10.35s
material-ui - node (v8.9.0, x64)
Memory used 463,377k (± 0.01%) 463,212k (± 0.01%) -165k (- 0.04%) 463,061k 463,333k
Parse Time 2.38s (± 0.56%) 2.37s (± 0.59%) -0.01s (- 0.21%) 2.34s 2.40s
Bind Time 0.78s (± 1.21%) 0.77s (± 1.29%) -0.00s (- 0.51%) 0.75s 0.79s
Check Time 17.17s (± 1.23%) 16.96s (± 0.95%) -0.21s (- 1.22%) 16.66s 17.29s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 20.32s (± 1.10%) 20.10s (± 0.81%) -0.22s (- 1.08%) 19.76s 20.43s
Angular - node (v8.9.0, x86)
Memory used 193,147k (± 0.03%) 193,030k (± 0.02%) -117k (- 0.06%) 192,954k 193,119k
Parse Time 2.43s (± 0.73%) 2.43s (± 0.77%) 0.00s ( 0.00%) 2.40s 2.49s
Bind Time 0.96s (± 0.71%) 0.96s (± 1.12%) -0.00s (- 0.52%) 0.94s 0.99s
Check Time 4.80s (± 0.47%) 4.75s (± 0.68%) -0.04s (- 0.88%) 4.66s 4.81s
Emit Time 5.95s (± 1.06%) 5.88s (± 1.04%) -0.06s (- 1.01%) 5.74s 6.03s
Total Time 14.14s (± 0.50%) 14.03s (± 0.53%) -0.11s (- 0.79%) 13.82s 14.18s
Monaco - node (v8.9.0, x86)
Memory used 193,098k (± 0.02%) 193,211k (± 0.03%) +113k (+ 0.06%) 193,092k 193,310k
Parse Time 1.89s (± 0.87%) 1.90s (± 0.66%) +0.00s (+ 0.21%) 1.87s 1.92s
Bind Time 0.68s (± 1.24%) 0.68s (± 0.50%) +0.00s (+ 0.59%) 0.68s 0.69s
Check Time 5.45s (± 0.47%) 5.44s (± 0.51%) -0.01s (- 0.26%) 5.36s 5.48s
Emit Time 2.67s (± 1.21%) 2.66s (± 0.73%) -0.01s (- 0.37%) 2.63s 2.71s
Total Time 10.69s (± 0.45%) 10.68s (± 0.44%) -0.01s (- 0.14%) 10.57s 10.78s
TFS - node (v8.9.0, x86)
Memory used 173,296k (± 0.02%) 173,344k (± 0.02%) +48k (+ 0.03%) 173,300k 173,439k
Parse Time 1.58s (± 0.73%) 1.57s (± 0.79%) -0.01s (- 0.44%) 1.55s 1.61s
Bind Time 0.61s (± 0.59%) 0.62s (± 0.94%) +0.00s (+ 0.49%) 0.61s 0.63s
Check Time 4.61s (± 0.96%) 4.62s (± 0.64%) +0.01s (+ 0.15%) 4.54s 4.69s
Emit Time 2.80s (± 1.13%) 2.77s (± 0.59%) -0.03s (- 1.14%) 2.73s 2.82s
Total Time 9.61s (± 0.65%) 9.58s (± 0.38%) -0.03s (- 0.27%) 9.50s 9.67s
material-ui - node (v8.9.0, x86)
Memory used 262,197k (± 0.01%) 262,127k (± 0.01%) -70k (- 0.03%) 262,037k 262,198k
Parse Time 2.41s (± 0.42%) 2.43s (± 0.41%) +0.02s (+ 0.75%) 2.42s 2.46s
Bind Time 0.66s (± 1.41%) 0.66s (± 1.51%) +0.00s (+ 0.30%) 0.65s 0.69s
Check Time 15.48s (± 0.38%) 15.52s (± 0.42%) +0.04s (+ 0.25%) 15.44s 15.74s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 18.55s (± 0.36%) 18.61s (± 0.40%) +0.06s (+ 0.33%) 18.51s 18.86s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-166-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 39084 10
Baseline master 10

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

Looks good; would it also be worth having an incremental test of adding/removing the possibly-await-thing, while the script/moduleness remains the same?

@rbuckton
Copy link
Member Author

I'll add one.

@rbuckton rbuckton merged commit fe33e61 into master Jun 19, 2020
@rbuckton rbuckton deleted the topLevelAwait2 branch June 19, 2020 06:43
cangSDARM added a commit to cangSDARM/TypeScript that referenced this pull request Jun 23, 2020
* upstream/master: (58 commits)
  Variadic tuple types (microsoft#39094)
  chore: resolve suggestions
  Expand auto-import to all package.json dependencies (microsoft#38923)
  inline local functions
  Update bigint declaration file (microsoft#38526)
  Update user baselines (microsoft#39077)
  LEGO: check in for master to temporary branch.
  Add missing index.ts files to user projects (microsoft#39163)
  Add reason for a disabled code action (microsoft#37871)
  Minor fix for assertion predicates (microsoft#38710)
  Update LKG (microsoft#39173)
  Reparse top level 'await' in modules (microsoft#39084)
  change
  chore: more change
  chore: resolve review
  chore: save space
  fix: lint error
  test: add test for it
  chore: make isJsxAttr required
  chore: revert change in checker
  ...

# Conflicts:
#	src/compiler/binder.ts
#	src/compiler/checker.ts
#	src/compiler/parser.ts
#	src/compiler/types.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[3.8] [BUG] TLA top-level await breaks with parenthesis
3 participants