dartdoc icon indicating copy to clipboard operation
dartdoc copied to clipboard

Link to type variable if mentioned in dartdoc `[T]`

Open maiermic opened this issue 10 years ago • 4 comments

I wrote a abstract generic class. Since its generic types have to follow some restrictions, I'd like to explain how to use/declare its generic type variables in a sub class. I would like to link to the particular type variable in my comment. Otherwise, it might be ambiguous to what the single letter (of a type variable) in my comment refers to.

maiermic avatar Jul 28 '15 06:07 maiermic

Have you tried something like:

class Foo<T extends Bar> ?

Please provide a short, self-contained example code and we'll take a look. Thanks!

sethladd avatar Jul 28 '15 15:07 sethladd

In my example I try to provide additional methods to an instance of type Wrapped. The class AbstractWrapper forwards all methods of its wrapped value. ConcreteWrapper inherits from AbstractWrapper and defines additional methods. Thus, you can use ConcreteWrapper instead of Wrapped with all methods of Wrapped and your additional methods of ConcreteWrapper. If you have an instance of Wrapped, simply wrap it with ConcreteWrapper and you are able to use your additional methods. Since ConcreteWrapper implements Wrapped, you can use it like Wrapped. For example you can pass ConcreteWrapper to a method that expects Wrapped.

/// Wrapper of [Wrapped] that forwards all methods on a wrapped value.
///
/// Inherit from this class to provide extra methods for [Wrapped].
///
/// [T] is the type of the generic class [Wrapped] that is wrapped by [AbstractWrapper]
/// [W] is the sub class itself that inherits from [AbstractWrapper].
abstract class AbstractWrapper<T, W extends AbstractWrapper<dynamic, S>> implements Wrapped<T> {
  /// Wrapped value of a generic type
  Wrapped<T> wrapped;

  /// Creates a new wrapper of the same type as this instance.
  ///
  /// It is used to wrap return values of forwarded methods again.
  W _newWrapper(Wrapped source);

  /// Forward method of [Wrapped]
  ///
  /// Returns a wrapper with the same generic type variable as this instance.
  /// Since generic type variables of [W] are not known, they can not be specified here.
  /// Use [WrapperType] as mixin with concrete sub class of [AbstractWrapper]
  @override
  W forward(T something) {
    return _newWrapper(wrapped.forward(something));
  }

  /// Forward method of [Wrapped]
  ///
  /// Returns a wrapper with an unkown generic type variable as this instance.
  @override
  W forward2(T something) {
    return _newWrapper(wrapped.forward2(something));
  }  
}

/// Mixin to provide known type variable to return value type of [AbstractWrapper] methods
/// in their sub class.
///
/// [T] is the kown type variable.
/// [W] is the concrete sub class of [AbstractWrapper] that uses [WrapperType] as a mixin.
abstract class WrapperType<T, W extends AbstractWrapper<T, W>> {
  W forward(T something);
}

/// Wrapper that provides additional helpful methods for an instance of [Wrapped].
class ConcreteWrapper<T> extends AbstractWrapper<T, ConcreteWrapper> with WrapperType<T, ConcreteWrapper<T>> {
  ConcreteWrapper(wrapped) : super(wrapped);

  @override
  ConcreteWrapper _newWrapper(Wrapped source) {
    return new ConcreteWrapper(source);
  }

  ConcreteWrapper<T> helpful(Iterable[T] values) { ... }
}

I explain in my example how to use type variables, because it is not that obvious in this case. My explanations are clearer if I can refer/link to type variables. Another term of type variable is type parameter. I'd like to explain how to use parameters and likewise type parameters, if it is not self explaining.

Ps: Feel free to ask questions to my code and suggest an alternative to links to a type variable.

maiermic avatar Jul 28 '15 21:07 maiermic

Links to type parameters don't currently work, but they shouldn't warn. It also isn't clear to me what they should link to, except possibly the abstract class which defined them?

jcollins-g avatar May 15 '17 17:05 jcollins-g