Hide constructors for "super" enums
It's never valid for user code to call it. It shouldn't be exposed.
An attempt to call Enum() directly is currently rejected because Enum is an abstract class, and the documentation says that it's an error for a non-platform class to be a subclass (among other things) of Enum.
This means that we basically already have a good enough explanation for why we can't call that constructor directly, and we can't call it from a regular class via super().
The part that could create some confusion is that it is not allowed to have an explicit superinitializer in a constructor in an enum declaration, and that's a funny/unexplained exception.
enum E { one; const E(): super(); } // 'The enum constructor can't have a 'super' initializer.
@lrhn, WDYT?
I think @kevmoo meant "enhanced" enums. Like the constructor shown on this page: https://api.dart.dev/stable/2.18.4/dart-io/HttpClientResponseCompressionState.html
I'm not quite sure I understand the difference: HttpClientResponseCompressionState is an enum declaration, and it uses the enhanced feature set of enum declarations that we enabled in Dart 2.17. The same things are true for enum E { one; const E(): super(); }.
So both enum declarations can (and do) have constructors, and both of them will have a compile-time error if there is a superinitializer. The question is whether that error is too confusing, and something should be changed (in some document, or in the error message, or ..., whatever makes sense).
[Edit] Just looked again, and HttpClientResponseCompressionState does not use any of the enhanced features. But I think that doesn't matter: The question is still whether something should be changed such that the treatment of the Enum constructor is explained better, and the only issue I can see is that it may be surprising that a constructor in an enum declaration can't call super().
(Of course, an enum isn't actually a subclass of Enum, but we pretend that it is, so we should probably also pretend that super() in an enum constructor would have called the Enum constructor.)
"Super" is a red herring here. super(), super., and Enum have nothing to do with this. :)
Right now, you can write:
enum MyEnum {
final int value;
const Enum(this.value);
}
If you run Dartdoc on this, it generates a Dartdoc page that says:
Constructors
MyEnum() const
It documents the constructor on this enum, which makes it look like the constructor is part of the type's public API. But it is a compile-error for anyone (outside of the enum) to try to call this constructor.
So the question this issue is about is, should dartdoc generate constructor docs for enum types or not? I think the answer is probably "no". An enum's constructor is essentially private: it can't be invoked from outside of the enum where it's defined, and dartdoc doesn't generate docs for other private members.
@munificent wrote:
the question this issue is about is, should dartdoc generate constructor docs for enum types or not?
Right, that's much more interesting than the near-trivial constructor of Enum/_Enum.
Here's an example from the feature specification about enhanced enums:
enum Complex<T extends Pattern> with EnumComparable<Complex> implements Pattern {
// Value declarations.
whitespace<RegExp>(r"\s+", RegExp.new),
alphanum<RegExp>.captured(r"\w+", RegExp.new),
anychar<Glob>("?", Glob.new),
;
... // Constructors, other member declarations.
}
Of course, it would be possible to give each value declaration a detailed DartDoc, explaining that value from scratch.
I believe this approach is quite common: Take a look at DisplayFeatureState, section 'Values': Each value is described separately.
However, each value declaration also relies on the semantics of a constructor in the enum declaration, and some constructors could be doing non-trivial work. The DartDoc page about DisplayFeatureState already shows the relevant constructor invocation at the end (for instance, the paragraph about unknown shows const DisplayFeatureState(0) at the end).
With that in mind, I think a paragraph describing whitespace<RegExp>(r"\s+", RegExp.new) could have a reasonably short description plus a link to the relevant constructor, and the DartDoc page about that constructor could then explain all the details that are relevant to every value created by this constructor.
I think there would be some situations where the ability to do this is more helpful than an approach where we treat enum constructors as irrelevant to clients.
I think DartDoc should not expose non-public API. It doesn't show private members, and it shouldn't show enum-class constructors either. So, agree with original posting.
It should be enough to document the class, fields and enum values to explain what each means. The constructor is not important when you can (and should) document every object created by it instead. It's a "how" that no longer matters when you have the "what".
With that in mind, I think a paragraph describing
whitespace<RegExp>(r"\s+", RegExp.new)could have a reasonably short description plus a link to the relevant constructor, and the DartDoc page about that constructor could then explain all the details that are relevant to every value created by this constructor.
Keep in mind that with #3096, it could be possible to document the private constructor as well (but at the cost of documenting everything private)
It seems like there's a bit of a bucketing problem between constructors that are private, public, or ... local? Enums seem to be a case where we have a constructor that not only can't be used by other libraries (similar to private), but can't be used in other contexts in the same library. This seems analogous to a locally declared variable inside of a function. IMO an implementation should reflect that, not by pretending that the constructor is private, but by never documenting it all.
Yeah I think this is a valid request.