Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all classes from a package

Tags:

haxe

I'd like a (platform independent) way to list all classes from a package.

A possible way would be get a list of all classes known by Haxe, then filtering through it.

like image 381
vbence Avatar asked Dec 08 '14 11:12

vbence


People also ask

How can you directly access all classes in the package in Java?

Class loaders are dynamic. Hence, finding classes in a package is essentially a file system operation rather than one done by using Java Reflection. However, we can write our own class loaders or examine the classpath to find classes inside a package.

How do I get all classes in a classpath?

You can get all classpath roots by passing an empty String into ClassLoader#getResources() . Enumeration<URL> roots = classLoader. getResources("");

How many classes can be in a package?

There is no limit in the specification, so you can put classes into the package until hitting a technical limitation. If not hitting a limit at the file system or archive format, the runtime implementation likely uses arrays or collections to hold the classes, which limits the number to something close to 2³¹.


1 Answers

I made a macro to help with just this. It's in the compiletime haxelib.

haxelib install compiletime

And then add it to your build (hxml file):

-lib compiletime

And then use it to import your classes:

// All classes in this package, including sub packages.
var testcases = CompileTime.getAllClasses("my.package"); 

// All classes in this package, not including sub packages.
var testcases = CompileTime.getAllClasses("my.package",false); 

// All classes that extend (or implement) TestCase
var testcases = CompileTime.getAllClasses(TestCase);

// All classes in a package that extend TestCase
var testcases = CompileTime.getAllClasses("my.package",TestCase);

And then you can iterate over them:

for ( testClass in testcases ) {
    var test = Type.createInstance( testClass, [] );
}

Please note, if you never have "import some.package.SomeClass" in your code, that class will never be included, because of dead code elimination. So if you want to make sure it gets included, even if you never explicitly call it in your code, you can do something like this:

CompileTime.importPackage( "mygame.levels" );
CompileTime.getAllClasses( "mygame.levels", GameLevel );

How it works

CompileTime.getAllClasses is a macro, and what it does is:

  • Waits until compilation is finished, and we know all of the types / classes in our app.
  • Go through each one, and see if it is in the specified package
  • See also if it extends (or implements) the specified class/interface
  • If it does, add the class name to some special metadata - @classLists(...) metadata on the CompileTimeClassList file, containing the names of all the matching classes.
  • At runtime, use the metadata, together with Type.resolveClass(...) to create a list of all matching types.
like image 161
Jason O'Neil Avatar answered Sep 25 '22 00:09

Jason O'Neil