dartdoc icon indicating copy to clipboard operation
dartdoc copied to clipboard

Hide "noSuchMethod"

Open jpdup opened this issue 11 months ago • 12 comments

Given a simple class like

class Foobar {
}

Pana will report public API as

METHODS section 

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.

(inherited)

Pana lists the inherited noSuchMethod from Object in the methods section for a simple class. While it's marked as 'inherited,' it might be better to either exclude such fundamental inherited methods from the main methods list or present them in a separate 'Inherited Methods' section for better clarity, especially for very basic classes."

jpdup avatar Apr 08 '25 08:04 jpdup

Is this a dartdoc issue?

sigurdm avatar Apr 08 '25 08:04 sigurdm

We already remove the noSuchMethod from the reported API list: https://github.com/dart-lang/pana/blob/master/lib/src/dartdoc/index_to_pubdata.dart#L12

At least we should. @jpdup: can you provide a public package on pub.dev that has this issue in the report?

isoos avatar Apr 08 '25 09:04 isoos

Here's my smallest and simplest class, it's called IntOffset the code is available on GitHub here

https://github.com/vteam-com/TEXTify/blob/main/lib/int_offset.dart

The PubDev Pana/Dart doc generated documentation is here

https://pub.dev/documentation/textify/latest/int_offset/IntOffset-class.html

Image

jpdup avatar Apr 09 '25 06:04 jpdup

@jpdup: pana is concerned about analysis and scoring, this issue is for dartdoc, I'll move it to that repository. However, I don't recall that this is a recent change, it was like that for a long time. Maybe we should display it with different color or contrast? In the sidebar the method name is lighter, indicating it is inherited.

isoos avatar Apr 09 '25 07:04 isoos

@sigurdm could you please move the issue? I don't have the permissions to do so.

isoos avatar Apr 09 '25 07:04 isoos

While it's marked as 'inherited,' it might be better to either exclude such fundamental inherited methods from the main methods list or present them in a separate 'Inherited Methods' section for better clarity, especially for very basic classes."

What is the reason to exclude it or present it separately?

For the "present it separately" suggestion, we've taken a pretty strong stance on having fewer alphabetical sections. (But I think we could do more; I think Error classes should be listed with other classes.) It is easier to scan fewer alphabetical sections for something you are looking for. Scanning one alphabetical list is easier than scanning 4.

Especially for very basic classes

Making inherited members sometimes be in their own list, and sometimes not, is even worse. Now you really don't know where to look.

srawlins avatar Apr 17 '25 23:04 srawlins

Thanks for the thoughtful response!

To answer the question about “why”: I think inherited members (like hashCode, runtimeType, and noSuchMethod) could benefit from being separated or optionally hidden.

It’s mainly about decluttering and staying true to the authored API, helping readers quickly focus on what the library explicitly provides, versus what’s automatically inherited from Object. It improves clarity, confidence, and scanning efficiency for real APIs — especially in minimal classes where inherited members can easily overwhelm authored ones.

Separating them (even collapsed by default) would better reflect intentional design, while still making them accessible if needed.

While testing this, I also noticed a related “automated” documentation detail that, as the API author, I would not have documented this way — it feels like a side effect of the language mechanics:

DartDoc shows “new” under constructors even though Dart no longer requires the new keyword, and the constructor in Dart is always named after the class itself.

For example, it currently shows:

CONTRUCTORS
new

Image

a more faithful representation would be:

IntOffset()
IntOffset(int x, int y)

This would keep the documentation consistent with modern Dart style and avoid confusion about the role of new.

Thanks again for considering these points — I really appreciate the discussion around keeping DartDoc clean, modern, and faithful to authors’ code!

jpdup avatar Apr 20 '25 13:04 jpdup

Thanks for the info. I think the request to collapse or hide or mute inherited docs is covered by https://github.com/dart-lang/dartdoc/issues/2057.

srawlins avatar Apr 21 '25 16:04 srawlins

I do think it's fair to argue that methods/properties/operators inherited from Object could be particularly uninteresting, speaking about:

  • hashCode
  • operator ==
  • toString
  • noSuchMethod
  • runtimeType

When inherited from Object, not when inherited from a class/mixin other than Object.


For:

  • noSuchMethod
  • runtimeType

I do not what to know what these are, I don't want to read about them in docs.

For:

  • hashCode
  • operator ==
  • toString

I want to know if the class I'm looking at has an implementation different from the one provided by Object. If the object just inherits the implementation from Object, I don't care. I probably do care if the class inherits the implementation from a different class.


How to best reduce the distraction caused by these I don't know.

  • Making additional sections might not be desirable.
  • Hiding/collaposing/muting inherited docs might help, but there is perhaps a difference between something inherited from Object and something inherited from, say BaseClient.
  • Making a special case for the methods on Object is an option. Deciding that the particular methods inherited from Object are so unnoteworthy that we'll omit them from docs if they are not overridden elsewhere. But this kind of special casing is also ugly.
  • Convincing the language team that runtimeType should be deprecated and marked // @nodoc is probably a hard sell, but the functionality it offers could probably be exposed with a static method on Object, like Object.getRuntimeType(someObject) -> Type. Doing something like this for noSuchMethod might not be entirely impossible, but probably hard, doing something like that for hashCode, etc. seems impossible 🤣

I don't know what other options there may be.


But, I think it's fair to recognize that methods inherited from Object, when not overridden are largely just noise. That said, it's quite possible that it's better to accept the noise, than try to fix it.

jonasfj avatar Apr 30 '25 11:04 jonasfj

Maybe some styling of all inherited methods to make them seem "less important" could be used:

Mockup: Image

sigurdm avatar May 01 '25 08:05 sigurdm

we discussed this offline, and the concept of "inherited" is often hard to define

  • What about mixed in methods, are they inherited?
  • What if you inherit from base classes outside the public API, should they still count as "inherited"?
  • ...

sigurdm avatar May 01 '25 12:05 sigurdm

I have been working on a CL that significantly reduces the amount of "inherited" code we generate. The idea is that an overridden member (method, field, getter, setter, operator) that has an implementation but does not have new documentation should be considered "inherited" and not get its own page.

Jacob Richman's big example to me was that ListView should not have it's own page for debugFillProperties. It doesn't design or document it's own method here; it only provides an implementation of something declared and documented way above in its type hierarchy: Diagnosticable.

The big consequence here, is that if we changed the HTML output to show one long page for the ListView class (really long), without linking out to the members in their own pages, then it is very silly to show debugFillProperties on this page. The docs there even have their own embedded YouTube video!

I hope to send out that CL soon; I'll send out the design it is based on as well.

srawlins avatar May 01 '25 13:05 srawlins