Skip to content

Support for auto-accessor fields from the Stage 3 Decorators proposal #49705

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
Sep 12, 2022

Conversation

rbuckton
Copy link
Contributor

@rbuckton rbuckton commented Jun 28, 2022

This PR adds support for accessor field declarations described in the Stage 3 Decorators proposal.

An Auto-Accessor is a field declaration that will be transformed by the runtime into a pair of get and set accessors that access a private backing field:

class C {
  accessor x = 1;
}
// is transformed into
class C {
  // actual field is named `#x accessor storage` so that it isn't user-reachable
  #x_accessor_storage = 1;
  get x() { return this.#x_accessor_storage; }
  set x(value) { this.#x_accessor_storage = value; }
}

When you use --target ESNext, accessor fields will be left as is to be transformed by the runtime. Any earlier --target will result in TypeScript downleveling the accessor field to a compatible runtime implementation.

Auto-Accessor fields have several capabilities:

  • Allows subclasses to override the get/set without a superclass field potentially shadowing the property during initialization.
  • A decorator applied to an auto-accessor receives the get and set accessor pair and can replace them without changing the runtime shape of the class.
  • Native ECMAScript decorators will be able to replace the initializer.

In addition, there are several rules around the use of the accessor keyword:

  • accessor fields require a minimum of --target ES2015, similar to our support for private identifiers (i.e., #x) and for the same reasons (a dependency on WeakMap/WeakSet).
  • accessor may only appear in front of field declarations on a class. It is not supported in interface or object type literals.
  • accessor cannot be used with readonly or declare on the same field declaration.
  • accessor can be used in an ambient class declaration.
  • accessor field declarations can be decorated with TypeScript's legacy decorators (i.e., under --experimentalDecorators). They will behave as if you decorated a get or set declaration (i.e., you will receive a PropertyDescriptor at runtime with both get and set functions).
  • A field explicitly marked with accessor will also be marked with accessor in the output declaration file.
  • An accessor field does not make a class nominal, despite the synthetic private backing field.
  • The TypeScript Symbol for an accessor field is not a SymbolFlags.Property, but rather a SymbolFlags.GetAccessor | SymbolFlags.SetAccessor.

NOTE: This is not an implementation of the full Stage 3 Decorators proposal as that effort is still in progress.

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Jun 28, 2022
@rbuckton
Copy link
Contributor 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 28, 2022

Heya @rbuckton, I've started to run the diff-based user code test suite on this PR at b3487dc. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

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

@rbuckton
Copy link
Contributor Author

@typescript-bot perf test

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

Heya @rbuckton, I've started to run the perf test suite on this PR at a37f09a. 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 - main..49705

Metric main 49705 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 359,575k (± 0.02%) 359,665k (± 0.02%) +90k (+ 0.02%) 359,557k 359,933k
Parse Time 2.08s (± 0.45%) 2.09s (± 0.49%) +0.01s (+ 0.43%) 2.07s 2.11s
Bind Time 0.90s (± 0.66%) 0.90s (± 0.74%) +0.00s (+ 0.45%) 0.89s 0.91s
Check Time 5.97s (± 0.45%) 5.97s (± 0.46%) -0.00s (- 0.07%) 5.91s 6.04s
Emit Time 6.09s (± 0.54%) 6.18s (± 0.54%) +0.09s (+ 1.50%) 6.12s 6.29s
Total Time 15.03s (± 0.28%) 15.13s (± 0.36%) +0.10s (+ 0.67%) 15.04s 15.31s
Compiler-Unions - node (v10.16.3, x64)
Memory used 206,445k (± 0.04%) 206,542k (± 0.02%) +98k (+ 0.05%) 206,449k 206,633k
Parse Time 0.84s (± 1.07%) 0.83s (± 0.85%) -0.01s (- 0.84%) 0.81s 0.84s
Bind Time 0.53s (± 0.71%) 0.53s (± 1.71%) +0.00s (+ 0.76%) 0.51s 0.55s
Check Time 8.06s (± 0.78%) 8.04s (± 0.46%) -0.01s (- 0.15%) 7.98s 8.13s
Emit Time 2.50s (± 0.62%) 2.52s (± 0.73%) +0.02s (+ 0.88%) 2.48s 2.56s
Total Time 11.91s (± 0.62%) 11.93s (± 0.41%) +0.01s (+ 0.10%) 11.86s 12.06s
Monaco - node (v10.16.3, x64)
Memory used 343,924k (± 0.02%) 344,020k (± 0.02%) +96k (+ 0.03%) 343,897k 344,128k
Parse Time 1.59s (± 0.60%) 1.59s (± 0.14%) -0.01s (- 0.38%) 1.58s 1.59s
Bind Time 0.77s (± 0.67%) 0.77s (± 1.36%) +0.00s (+ 0.26%) 0.76s 0.80s
Check Time 5.95s (± 0.41%) 5.95s (± 0.41%) +0.01s (+ 0.08%) 5.89s 5.99s
Emit Time 3.25s (± 0.81%) 3.30s (± 0.43%) +0.05s (+ 1.54%) 3.27s 3.33s
Total Time 11.56s (± 0.26%) 11.61s (± 0.30%) +0.05s (+ 0.41%) 11.54s 11.69s
TFS - node (v10.16.3, x64)
Memory used 305,148k (± 0.03%) 305,218k (± 0.02%) +71k (+ 0.02%) 305,022k 305,370k
Parse Time 1.28s (± 0.46%) 1.28s (± 0.37%) -0.00s (- 0.31%) 1.27s 1.29s
Bind Time 0.72s (± 0.80%) 0.73s (± 0.80%) +0.01s (+ 0.97%) 0.72s 0.74s
Check Time 5.39s (± 0.34%) 5.40s (± 0.55%) +0.01s (+ 0.26%) 5.33s 5.48s
Emit Time 3.43s (± 0.80%) 3.51s (± 1.31%) +0.08s (+ 2.39%) 3.43s 3.63s
Total Time 10.82s (± 0.36%) 10.91s (± 0.66%) +0.09s (+ 0.85%) 10.77s 11.08s
material-ui - node (v10.16.3, x64)
Memory used 469,038k (± 0.01%) 469,122k (± 0.01%) +85k (+ 0.02%) 468,996k 469,237k
Parse Time 1.82s (± 0.64%) 1.83s (± 0.65%) +0.01s (+ 0.49%) 1.82s 1.87s
Bind Time 0.70s (± 1.72%) 0.69s (± 1.70%) -0.01s (- 1.15%) 0.67s 0.71s
Check Time 14.52s (± 0.93%) 14.50s (± 0.65%) -0.02s (- 0.17%) 14.36s 14.74s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 17.04s (± 0.82%) 17.02s (± 0.55%) -0.02s (- 0.15%) 16.88s 17.24s
xstate - node (v10.16.3, x64)
Memory used 580,972k (± 1.25%) 584,565k (± 1.68%) +3,594k (+ 0.62%) 577,878k 610,985k
Parse Time 2.59s (± 0.28%) 2.59s (± 0.38%) -0.00s (- 0.00%) 2.57s 2.61s
Bind Time 1.02s (± 0.81%) 1.03s (± 0.56%) +0.00s (+ 0.20%) 1.01s 1.04s
Check Time 1.54s (± 0.60%) 1.54s (± 0.60%) -0.00s (- 0.26%) 1.52s 1.56s
Emit Time 0.07s (± 3.14%) 0.07s (± 4.13%) +0.00s (+ 1.41%) 0.07s 0.08s
Total Time 5.22s (± 0.27%) 5.22s (± 0.30%) +0.00s (+ 0.08%) 5.18s 5.25s
Angular - node (v12.1.0, x64)
Memory used 337,081k (± 0.08%) 337,208k (± 0.02%) +127k (+ 0.04%) 337,082k 337,408k
Parse Time 2.10s (± 0.51%) 2.09s (± 0.55%) -0.00s (- 0.05%) 2.08s 2.13s
Bind Time 0.86s (± 0.77%) 0.87s (± 0.69%) +0.00s (+ 0.35%) 0.85s 0.88s
Check Time 5.78s (± 0.60%) 5.79s (± 0.47%) +0.01s (+ 0.24%) 5.72s 5.84s
Emit Time 6.37s (± 0.80%) 6.44s (± 0.54%) +0.07s (+ 1.12%) 6.37s 6.50s
Total Time 15.10s (± 0.53%) 15.18s (± 0.28%) +0.08s (+ 0.54%) 15.07s 15.28s
Compiler-Unions - node (v12.1.0, x64)
Memory used 194,078k (± 0.07%) 194,166k (± 0.03%) +88k (+ 0.05%) 194,024k 194,323k
Parse Time 0.82s (± 0.57%) 0.82s (± 1.01%) +0.00s (+ 0.61%) 0.81s 0.85s
Bind Time 0.55s (± 0.90%) 0.55s (± 1.09%) 0.00s ( 0.00%) 0.54s 0.56s
Check Time 7.57s (± 0.59%) 7.56s (± 0.61%) -0.01s (- 0.17%) 7.48s 7.72s
Emit Time 2.50s (± 1.00%) 2.56s (± 0.65%) +0.06s (+ 2.36%) 2.53s 2.61s
Total Time 11.43s (± 0.40%) 11.48s (± 0.39%) +0.05s (+ 0.45%) 11.42s 11.63s
Monaco - node (v12.1.0, x64)
Memory used 326,878k (± 0.01%) 327,004k (± 0.02%) +127k (+ 0.04%) 326,895k 327,135k
Parse Time 1.57s (± 0.90%) 1.57s (± 0.65%) -0.01s (- 0.57%) 1.55s 1.59s
Bind Time 0.76s (± 0.63%) 0.76s (± 0.87%) +0.00s (+ 0.40%) 0.75s 0.78s
Check Time 5.77s (± 0.40%) 5.77s (± 0.33%) -0.00s (- 0.02%) 5.74s 5.82s
Emit Time 3.31s (± 0.99%) 3.32s (± 0.33%) +0.01s (+ 0.36%) 3.30s 3.35s
Total Time 11.42s (± 0.40%) 11.42s (± 0.22%) +0.00s (+ 0.03%) 11.38s 11.49s
TFS - node (v12.1.0, x64)
Memory used 289,609k (± 0.05%) 289,827k (± 0.02%) +218k (+ 0.08%) 289,687k 289,958k
Parse Time 1.30s (± 0.51%) 1.29s (± 0.58%) -0.01s (- 1.00%) 1.27s 1.30s
Bind Time 0.72s (± 0.66%) 0.73s (± 0.61%) +0.01s (+ 0.69%) 0.72s 0.74s
Check Time 5.32s (± 0.31%) 5.32s (± 0.35%) -0.01s (- 0.11%) 5.28s 5.38s
Emit Time 3.53s (± 0.91%) 3.54s (± 1.06%) +0.00s (+ 0.06%) 3.43s 3.63s
Total Time 10.88s (± 0.30%) 10.87s (± 0.43%) -0.01s (- 0.10%) 10.78s 11.03s
material-ui - node (v12.1.0, x64)
Memory used 448,120k (± 0.01%) 448,113k (± 0.07%) -7k (- 0.00%) 446,935k 448,419k
Parse Time 1.83s (± 0.45%) 1.82s (± 0.56%) -0.00s (- 0.27%) 1.80s 1.84s
Bind Time 0.68s (± 0.99%) 0.68s (± 0.59%) +0.00s (+ 0.30%) 0.67s 0.69s
Check Time 12.94s (± 0.61%) 12.98s (± 0.80%) +0.03s (+ 0.27%) 12.79s 13.20s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.45s (± 0.52%) 15.48s (± 0.67%) +0.04s (+ 0.23%) 15.29s 15.71s
xstate - node (v12.1.0, x64)
Memory used 546,514k (± 1.31%) 546,666k (± 1.31%) +152k (+ 0.03%) 543,230k 575,660k
Parse Time 2.54s (± 0.42%) 2.54s (± 0.35%) -0.00s (- 0.16%) 2.52s 2.56s
Bind Time 1.03s (± 1.49%) 1.05s (± 1.32%) +0.02s (+ 1.75%) 1.02s 1.07s
Check Time 1.49s (± 0.62%) 1.48s (± 0.40%) -0.00s (- 0.27%) 1.47s 1.50s
Emit Time 0.07s (± 0.00%) 0.07s (± 0.00%) 0.00s ( 0.00%) 0.07s 0.07s
Total Time 5.13s (± 0.35%) 5.14s (± 0.39%) +0.01s (+ 0.21%) 5.11s 5.19s
Angular - node (v14.15.1, x64)
Memory used 335,268k (± 0.01%) 335,379k (± 0.01%) +111k (+ 0.03%) 335,325k 335,439k
Parse Time 2.07s (± 0.84%) 2.07s (± 0.51%) +0.00s (+ 0.19%) 2.05s 2.09s
Bind Time 0.90s (± 0.44%) 0.90s (± 0.54%) +0.01s (+ 0.56%) 0.89s 0.91s
Check Time 5.73s (± 0.44%) 5.75s (± 0.49%) +0.01s (+ 0.24%) 5.70s 5.81s
Emit Time 6.39s (± 0.65%) 6.50s (± 0.54%) +0.11s (+ 1.80%) 6.43s 6.59s
Total Time 15.08s (± 0.47%) 15.22s (± 0.33%) +0.14s (+ 0.94%) 15.11s 15.34s
Compiler-Unions - node (v14.15.1, x64)
Memory used 192,576k (± 0.11%) 192,775k (± 0.02%) +199k (+ 0.10%) 192,671k 192,828k
Parse Time 0.85s (± 0.79%) 0.85s (± 0.68%) +0.00s (+ 0.35%) 0.84s 0.86s
Bind Time 0.57s (± 0.87%) 0.57s (± 0.58%) -0.00s (- 0.87%) 0.56s 0.58s
Check Time 7.66s (± 0.51%) 7.62s (± 0.27%) -0.04s (- 0.51%) 7.58s 7.67s
Emit Time 2.52s (± 0.91%) 2.56s (± 0.73%) +0.04s (+ 1.59%) 2.52s 2.60s
Total Time 11.60s (± 0.40%) 11.60s (± 0.23%) +0.00s (+ 0.01%) 11.53s 11.67s
Monaco - node (v14.15.1, x64)
Memory used 325,635k (± 0.01%) 325,714k (± 0.01%) +79k (+ 0.02%) 325,665k 325,753k
Parse Time 1.58s (± 0.47%) 1.58s (± 0.42%) +0.00s (+ 0.19%) 1.57s 1.60s
Bind Time 0.79s (± 1.07%) 0.80s (± 0.63%) +0.00s (+ 0.51%) 0.79s 0.81s
Check Time 5.68s (± 0.48%) 5.68s (± 0.60%) +0.01s (+ 0.14%) 5.61s 5.78s
Emit Time 3.37s (± 0.80%) 3.41s (± 0.85%) +0.04s (+ 1.34%) 3.36s 3.47s
Total Time 11.41s (± 0.27%) 11.47s (± 0.54%) +0.06s (+ 0.49%) 11.36s 11.63s
TFS - node (v14.15.1, x64)
Memory used 288,777k (± 0.01%) 288,863k (± 0.01%) +86k (+ 0.03%) 288,799k 288,932k
Parse Time 1.34s (± 1.57%) 1.32s (± 1.22%) -0.02s (- 1.64%) 1.29s 1.36s
Bind Time 0.77s (± 4.87%) 0.75s (± 2.28%) -0.02s (- 2.22%) 0.73s 0.81s
Check Time 5.31s (± 0.49%) 5.31s (± 0.38%) +0.00s (+ 0.08%) 5.28s 5.37s
Emit Time 3.57s (± 1.76%) 3.67s (± 0.52%) +0.10s (+ 2.89%) 3.63s 3.71s
Total Time 10.98s (± 0.72%) 11.06s (± 0.36%) +0.07s (+ 0.66%) 10.98s 11.14s
material-ui - node (v14.15.1, x64)
Memory used 446,327k (± 0.01%) 446,406k (± 0.01%) +79k (+ 0.02%) 446,349k 446,443k
Parse Time 1.87s (± 0.54%) 1.87s (± 0.47%) -0.00s (- 0.21%) 1.85s 1.89s
Bind Time 0.73s (± 1.32%) 0.73s (± 0.91%) -0.00s (- 0.14%) 0.71s 0.74s
Check Time 13.24s (± 1.33%) 12.99s (± 0.28%) -0.25s (- 1.90%) 12.90s 13.08s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.84s (± 1.15%) 15.59s (± 0.24%) -0.26s (- 1.62%) 15.52s 15.69s
xstate - node (v14.15.1, x64)
Memory used 541,032k (± 0.00%) 541,209k (± 0.00%) +177k (+ 0.03%) 541,149k 541,273k
Parse Time 2.60s (± 0.48%) 2.60s (± 0.33%) +0.00s (+ 0.08%) 2.58s 2.61s
Bind Time 1.15s (± 1.35%) 1.16s (± 1.10%) +0.01s (+ 1.04%) 1.13s 1.19s
Check Time 1.53s (± 0.39%) 1.53s (± 0.44%) -0.00s (- 0.13%) 1.52s 1.55s
Emit Time 0.07s (± 4.66%) 0.07s (± 4.92%) +0.00s (+ 1.37%) 0.07s 0.08s
Total Time 5.35s (± 0.48%) 5.36s (± 0.28%) +0.01s (+ 0.22%) 5.33s 5.39s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-210-generic
Architecturex64
Available Memory16 GB
Available Memory15 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)
  • xstate - node (v10.16.3, x64)
  • xstate - node (v12.1.0, x64)
  • xstate - node (v14.15.1, x64)
Benchmark Name Iterations
Current 49705 10
Baseline main 10

Developer Information:

Download Benchmark

@rbuckton
Copy link
Contributor Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

Heya @rbuckton, I've started to run the diff-based user code test suite on this PR at 54024cf. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 28, 2022

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

@typescript-bot
Copy link
Collaborator

Heya @rbuckton, I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here.

@typescript-bot
Copy link
Collaborator

@rbuckton
Great news! no new errors were found between main..refs/pull/49705/merge

@fatcerberus
Copy link

fatcerberus commented Jun 28, 2022

Why is this a thing? Like, what problem does it actually solve (genuine question, not snark)? The generated accessors don't do anything and unlike, e.g., C#, changing a plain property to an accessor isn't generally an API break...

edit: Oh, I see, it's mostly because decorators will apparently make a distinction between field and accessor.

@rbuckton
Copy link
Contributor Author

Why is this a thing? Like, what problem does it actually solve (genuine question, not snark)? The generated accessors don't do anything and unlike, e.g., C#, changing a plain property to an accessor isn't generally an API break...

edit: Oh, I see, it's mostly because decorators will apparently make a distinction between field and accessor.

This was a requirement from VM implementers to avoid the potential hidden shape changes that could occur if you were able to convert a field declaration into an accessor dynamically rather than statically. It also helps to avoid issues with public field shadowing in cases like the following, such as with @observe in #48814:

class C {
  // observe attaches an accessor pair to C.prototype, but the field `x` is defined
  // on the instance, shadowing the accessor pair.
  @observe x = 1;
}

// vs
class C {
  // observe can now instead intercept the `{ get, set }` provided to attach its behavior.
  @observe accessor x = 1;
}

@sandersn
Copy link
Member

sandersn commented Jul 1, 2022

What are the assignability rules for auto-accessor fields? I guess that they're the same as a normal class field, but might be missing something.

@rbuckton
Copy link
Contributor Author

rbuckton commented Jul 1, 2022

They should be treated the same as we would a get/set pair.

@sandersn
Copy link
Member

sandersn commented Jul 6, 2022

Ah, that explains why the code in the checker is with the existing accessor code, not the property declaration code.

@ClementValot
Copy link

ClementValot commented Dec 20, 2022

Very naive question:
Is there a reason not to implement a similar keyword for public readonly properties which would do the same, but without a setter?

EDIT: I guess the keyword for readonly properties would be readonly :)
First thought is, the transpiler could, if target > ES2015, transform

class C {
    readonly x = 1;
}

into

class C {
    #x_accessor_storage = 1;
    get x() { return this.#x_accessor_storage; }
}

But that would be a very breaking change; which could be enabled by a --strictReadonly flag in the compiler options... Which would be a lot of work just for syntactic sugar

@wycats
Copy link

wycats commented Jan 4, 2023

Is there a reason not to implement a similar keyword for public readonly properties which would do the same, but without a setter?

More generally, is there a reason that readonly accessor isn't supported?

@rbuckton
Copy link
Contributor Author

rbuckton commented Jan 5, 2023

Is there a reason not to implement a similar keyword for public readonly properties which would do the same, but without a setter?

More generally, is there a reason that readonly accessor isn't supported?

It's not currently supported because the accessor isn't actually read-only (a setter is still generated) and that might break user expectations. Also, support for actual read-only accessors is planned as part of https://github.com/tc39/proposal-grouped-and-auto-accessors, which is blocked on any advancement until after Decorators reaches Stage 4.

With the full auto-accessors proposal, you could accomplish a true read-only accessor using the following syntax:

class C {
  accessor x { get; } = 1;
}

Which would transform into something like this:

class C {
    #x_accessor_storage = 1;
    get x() { return this.#x_accessor_storage; }
}

@Eghizio
Copy link

Eghizio commented Dec 1, 2024

Actually having a readonly accessor x; would be lovely to just generate the public getter ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

8 participants