dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.12k stars 1.57k forks source link

Consider shipping `package:meta` as `dart:meta`, similar to `dart:js_interop` and `dart:ffi` #54879

Open matanlurey opened 7 months ago

matanlurey commented 7 months ago

Originally, package:meta was a compromise (like package:js) to allow faster-iteration and versioned releases out of the SDK, and to (as far as I remember?) bypass arguments around what belongs in the core SDK or not. I believe that both of these rationales are dated and should be revisited.

Namely:

  1. All of the logic that actually powers package:meta is part of the SDK (the analyzer)
  2. It would be useful to allow SDK authors to use the annotations
  3. There are existing annotations in the SDK (@override, @deprecated) that make sense in dart:meta[^1]
  4. Flutter already ships package:meta by default as part of it's SDK
  5. The general trend (i.e. with dart:ffi, dart:js_interop, etc) is to move packages that are really SDK-vended into the SDK

Luckily I think this would be (mechanically) easy, as package:meta could just export 'dart:meta' until migrated.

[^1]: But for continuity could continue to be exported in dart:core.

lrhn commented 7 months ago

The general trend (i.e. with dart:ffi, dart:js_interop, etc) is to move packages that are really SDK-vended into the SDK

I'd say the trend is in the other direction. We're moving dart:html out of the SDK, into package:web, and for a long time the recommended JS interop was package:js, not dart:js. I wouldn't bet on dart:js_interop not becoming package:js_interop before the experiment is complete. (I don't know that it will, but I wouldn't be surprised if it happened. Because that is the direction of the trend.)

The best reason for having a package is that it can make breaking changes. A dart:... library is not versioned. You get what the SDK gives you, and you better like it. A breaking change is a big effort. The entire ecosystem needs to switch, or they won't be compatible with a new SDK relelase.

A package like package:meta can (theoretically) release a major version increment, and as long as the SDK keeps supporting old versions too, people can migrate gradually. A new major version of a commonly used non-dev-dependency is still hard, but at least one can do: meta: >=2.15.0 < 4.0.0 to support multiple major versions, if ones code is not affected by the breaking change.

The @override and @deprecated annotations predate package:meta. That's the main reason they're not in that package. Also that the SDK uses deprecated itself, but there are ways around that if we wanted to (we could just use another annotation, like @pragma("analyzer:deprecated"), and have the analyzer recognize both. Or we could declare them in dart:_meta and allow package:meta to access and export that, which is another trick we use to make things into packages.)

The meta package is really too dynamic to belong in a dart: library. It changes too often. It's driven by the analyzer's needs, not only tied to the language or SDK. Things like @visibleForTesting or @testGroup are simply too specialized to belong in dart: library (IMO). Getting into a dart: library that is available on all platforms is a very high bar to pass. Not all annotations would make it. It's very likely that there'd still be a package for annotations that are too specialized or too incongruent with the language design for us to want them in the SDK proper. The bar for getting into an opt-in package is much lower.

bwilkerson commented 7 months ago

I agree. The ability to define annotations that would never be approved for inclusion in the SDK and the ability to make breaking changes are valuable to the community. Not having a package would be detrimental to users.

And I think that moving in the direction of moving more functionality out of the dart: libraries and into packages is also a benefit for the community. I really hope that we do have package:js_interop rather than dart:js_interop.

matanlurey commented 5 months ago

I thought https://github.com/dart-lang/sdk/issues/53745#issuecomment-2073488842 was a compelling user report of the existence of package:meta not even being clear. I know about it because I've been working on/with Dart for years, but I imagine the vast majority of our users don't even know it exists or how to use it.

lrhn commented 5 months ago

Good thing you don't need to use package:meta. It's there if you want it, but you can program Dart perfectly well without ever using any annotation from package:meta. I know I do.

bwilkerson commented 5 months ago

@MaryaBelanger Re:

I thought #53745 (comment) was a compelling user report of the existence of package:meta not even being clear.

Is this something that we might want to try to address somehow in documentation?

MaryaBelanger commented 5 months ago

Is this something that we might want to try to address somehow in documentation?

Sure, I can try. I'll have to take a closer look at where this info might fit to make it as visible as possible (that seems to be the main issue).

Opened an issue here if anyone wants to throw their ideas in or discuss it further (will just be using the user report to inform otherwise): https://github.com/dart-lang/site-www/issues/5751