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

Dartdoc should support arguments comments, metadata #1259

Open
matanlurey opened this issue Oct 11, 2016 · 14 comments
Open

Dartdoc should support arguments comments, metadata #1259

matanlurey opened this issue Oct 11, 2016 · 14 comments
Labels
P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@matanlurey
Copy link

matanlurey commented Oct 11, 2016

Using long sets of named arguments is more common in Dart, especially given it's a style guide preference for Flutter.

For example:

class SweetToothState {
  /// Creates a new [SweetToothState].
  ///
  /// Given a [sugarEater] and a number of [stores], represents different bakeries and ice
  /// cream stores they still go to (haven't been banned from).
  factory SweetToothState({
    String sugarEater,
    int stores,
    List<String> allowed,
  }) = ...
}

It would be preferable to write:

class SweetToothState {
  /// Creates a new [SweetToothState] to represent an [sugarEater] wanting to go to [stores].
  factory SweetToothState({
    /// Name of the sugar eater.
    @required
    String sugarEater,

    /// How many stores the sugar eater wants to attend tonight.
    @required
    int stores,

    /// Optional; where the sugar eater is still allowed entry to.
    List<String> allowed,
  }) = ...
}

When using an IDE or viewing in Dartdoc, you could have nice doc comments for these complex sets of arguments. One addendum is that if you use a field initializer (this.) we should automatically use the public API comment there:

class SugarEaterState {
  /// Name of the sugar eater.
  @required
  final String sugarEater;

  SugarEaterState({this.sugarEater});
}
@sethladd
Copy link
Contributor

cc @Hixie

@sethladd sethladd added the type-enhancement A request for a change that isn't a bug label Oct 11, 2016
@sethladd
Copy link
Contributor

@matanlurey did you have any ideas how this would look when generated into HTML?

@matanlurey
Copy link
Author

I am not too creative - something similar to JavaDoc?

My main rationale here is actually for the IDE, when you type:

new SugarEaterState(...)

I'd like to see:

  |-----------------------------------|
  | Name of the sugar eater, required.|
  |-----------------------------------| 
  sugarEater:

@sethladd
Copy link
Contributor

My main rationale here is actually for the IDE

Ah, you might have to file a feature request with analyzer then?

@Hixie
Copy link
Contributor

Hixie commented Oct 11, 2016

Oh, yeah, being able to annotate individual arguments would be great for some of our classes. (And yeah, this.foo should automatically default the arg to the docs for foo.)

@marcoms
Copy link

marcoms commented Dec 21, 2018

IMO this is a pretty significant area where dartdoc could improve. Since there is no way for an editor to parse argument documentation, not being able to get any argument-specific documentation when hovering over it in VSCode or any other editor degrades the development experience quite a lot compared to Typescript for example (which a lot of React Native and web devs are coming from, me included).

Instead you have to search through the whole function documentation, and for functions with lots of arguments this gets quite painful.

Interestingly VSCode manages to extract docs for constructor arguments that correspond to member variables which themselves have doc comments. It would be nice if there was a way to do this for methods or freestanding functions

@matanlurey's suggestion of allowing doc comments above the arguments themselves seems quite elegant. Alternatively dartdoc could just support the commonly used @param syntax.

@jcollins-g jcollins-g added the P2 A bug or feature request we're likely to work on label Jan 31, 2019
@Jordan-Nelson
Copy link

Jordan-Nelson commented Jul 1, 2022

Are there any updates in this issue? I believe this is making it much harder for library developers to maintain proper documentation.

For example, it is very hard to provide good documentation in factory constructors. One scenario in which I see this is when using built_value, which has become very popular. Below is an example from their examples dir.

abstract class VerySimpleValue
    implements Built<VerySimpleValue, VerySimpleValueBuilder> {
  static Serializer<VerySimpleValue> get serializer =>
      _$verySimpleValueSerializer;

  int get value;

  factory VerySimpleValue(int value) => _$VerySimpleValue._(value: value);
  VerySimpleValue._();
}

If VerySimpleValue is exposed as part of the public API of my library, I want to ensure it has proper docs. If I add the docs below, consumers of my library will not see that when they use the constructor.

abstract class VerySimpleValue
    implements Built<VerySimpleValue, VerySimpleValueBuilder> {
  static Serializer<VerySimpleValue> get serializer =>
      _$verySimpleValueSerializer;

  /// Sets the value for the object
  int get value;

  factory VerySimpleValue(int value) => _$VerySimpleValue._(value: value);
  VerySimpleValue._();
}

I could do something like below, but this is repetitive and not what consumers would expect since it doesn't match what the docs would look like if this was a non-factory constructor with value as a member of VerySimpleValue.

abstract class VerySimpleValue
    implements Built<VerySimpleValue, VerySimpleValueBuilder> {
  static Serializer<VerySimpleValue> get serializer =>
      _$verySimpleValueSerializer;

  /// Sets the value for the object
  int get value;

  /// Very simple value
  ///
  /// [value] sets the value for the object
  factory VerySimpleValue(int value) => _$VerySimpleValue._(value: value);
  VerySimpleValue._();
}

I could use a template/macro to get rid of the repetition, but the docs become somewhat clunky, and again - not what consumers expect.

What I really want is to do this:

abstract class VerySimpleValue
  implements Built<VerySimpleValue, VerySimpleValueBuilder> {
static Serializer<VerySimpleValue> get serializer =>
    _$verySimpleValueSerializer;

/// {@template very_simple_value.value}
/// Sets the value for the object
/// {@endtemplate}
int get value;

/// Very simple value
factory VerySimpleValue({
  /// {@macro very_simple_value.value}
  required int value
}) => _$VerySimpleValue._(value: value);
VerySimpleValue._();
}

And then of course the doc for value would be visible to consumers using the factory constructor.

This would not involve any repeated code, and give consumers a good experience, with info about constructor arguments in a predictable location.

built_value and factory constructors are just one common use case I see, but this can be applied to many other cases. Take the simple class below.

class Foo {
  /// Foo class.
  /// 
  /// [name] does something
  const Foo({
    required this.value,
    required String name,
  }) : _name = 'foo_$name';

  /// doc for value
  final int value;

  final String _name;
}

I believe this is how the dart docs would suggest this class is commented. But this isn't a great DX. The consumer of Foo has to look in two different places to find the doc comments for the two arguments to the constructor.

@srawlins
Copy link
Member

srawlins commented Jul 1, 2022

No updates to this issue. I agree it would be a great enhancement.

@Jordan-Nelson
Copy link

Okay. Thanks for the quick response.

@Jordan-Nelson
Copy link

I want to add a more common example of where the DX could be improved incase it helps bump the priority of this.

ThemeData is a class most flutter developers use. The commonly used constructors are factory constructors. The ThemeData() factory constructor accepts 83 arguments, not counting deprecated arguments. There are great API docs for these, but you have to search though the source code to find them.

@navaronbracke
Copy link

Has there been more work on this? With the new JS interop functionality, this is something I would like to see being implemented.

Especially since there is now a concrete use case, documenting external factory constructors for anonymous types.

Today you can get the parameters documented if they have fields, but external factories might not have corresponding fields.

I.e.

import 'dart:js_interop';

/// Create a JS Object like `{foo: 'some sring', bar: 42}`,
/// using static interop.
@JS()
@anonymous
@staticInterop
class MyAnonType {
  external factory MyAnonType({
    String? foo,
    int bar,
  });
}

@srawlins
Copy link
Member

There has not been more work on this.

@g-apparence
Copy link

This could help many plugins and packages.

@CHB61
Copy link

CHB61 commented Feb 9, 2024

Interested to see this supported.

It would also be helpful for widgets like TextFormField where most parameters don't have dartdocs available since they are not class variables. Instead the dartdoc on the constructor says: "For documentation about the various parameters, see the [TextField] class and [TextField.new], the constructor".

In my case, I would like to do something like this:

class SelectableList<T> extends StatefulWidget {
  /// The initial value for a list.
  final List<T>? initialValueList;

  /// The initial value for a single item.
  final T? initialValueSingle;

  const SelectableList.single({
    super.key,
    /// either add dartdoc here, or would be nice if I could point to the respective class variable's dartdoc
    T? initialValue,
  })  : initialValueList = null,
        initialValueSingle = initialValue;

  const SelectableList.multi({
    super.key,
    List<T>? initialValue,
  })  : initialValueList = initialValue,
        initialValueSingle = null;

  @override
  State<SelectableList<T>> createState() => _SelectableListState<T>();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

10 participants