1

I am using the build package to take a .dart file and look for definitions of a certain class or its subclasses. Can ClassElement be used for subclasses too?

I am only expecting a single definition of a specific class to be within one file of the project, but there's no reason clients couldn't subclass and go wild.

Nate Bosch
  • 10,145
  • 2
  • 26
  • 22
Jacob Phillips
  • 8,841
  • 3
  • 51
  • 66
  • I think that should work using the `allSupertypes` method. https://github.com/dart-lang/source_gen/blob/master/source_gen/lib/src/type_checker.dart might help. See also how its used in https://github.com/dart-lang/json_serializable/search?q=typechecker&unscoped_q=typechecker – Günter Zöchbauer Sep 19 '18 at 13:57
  • I made a suggested edit to the question - normally when we talk about classes an "instance" means an object created with `new NameOfType();`. I think what you're looking for here are class "definitions" or "subclasses". – Nate Bosch Sep 20 '18 at 17:14
  • I actually was looking for an instance to be able to call `toString()` on it. I am just using a workaround where I give an example usage and people can copy it. No analyzer needed. – Jacob Phillips Sep 21 '18 at 08:55

1 Answers1

2

There is not a way to directly grab all subclasses, but you can find all classes and check if each one is a subclass of the one you're interested in.

Start by getting the LibraryElement for the file you're generating code for with BuildStep.inputLibrary. From there find all the classes in the library with var classes = libraryElement.units.expand((cu) => cu.types);. Then check if each one is a subclass of the class you are interested in by checking whether the ClassElement for the type you are interested in is in ClassElement.allSupertypes for the type you are checking. var subtypes = classes.where((c) => c.allSupertypes.contains(lookingFor));.

You may find the LibraryReader and TypeChecker utilities from source_gen useful.

Nate Bosch
  • 10,145
  • 2
  • 26
  • 22
  • What if the subclasses are inside different libraries (files, usually)? – Hugo Passos Feb 14 '20 at 17:04
  • I'm not aware of an efficient way to find them. The build system (and the analyzer's use within) doesn't have a notion of "full program", only the code reachable via imports of whatever file you are running on. Most likely you'd need to run a builder with the primary input being the "entrypoint" (that has a main()) and then walk over all transitive imports. – Nate Bosch Feb 18 '20 at 18:57