According to the documentation, the $classes macro supports a NAMED;PATTERN query where PATTERN is a glob. Does this glob support any kind of “exclude” option please? In particular, something like **[!$]* so as to exclude any fqn which contains a $ character?
I am trying to exclude nested, inner and anonymous classes here.
Thanks, I think both of these solutions would work… if only the names of inner, nested and anonymous classes actually contained a $ character to find! My println debugging has revealed that the class name I am matching against is:
com.foo.bar.MyClass.InnerClass
and not
com.foo.bar.MyClass$InnerClass
A consequence of the query using getClassName().getDottedOnly() here, I believe .
Cheers,
Chris
Edit: Yes, matching against getClassName().getFQN() would have the behaviour that I seek. So I guess the question becomes “Is this a bug? Or a request for a new feature (pretty) please”?
Hmm, the documentation says:
NAMED PATTERN The class fqn must match the given pattern.
To close the loop here, I added STATIC and INNER query types for the ${classes} macro to enable selection of non-inner or inner classes, respectively.
It is a bad idea to look for a $ in the class name as an indicator that it is an inner (or even nested) class. $ is a completely legitimate character in a Java identifier such as a class name.
I also updated the doc page for the ${classes} macro to be more clear on the form of the name used for each query type.
Hmmm. I would like to get one of these class files to look at it and see how it differs from a Java anonymous inner class. It would be better if Bnd could properly recognize these. Could you get one to me?
Thanks! In the example you sent, the member classes did not reference anything from the enclosing scope. So the generated class files are more member classes than inner classes.
When I changed the source code to reference a variable from the enclosing scope, then the generated class is an inner class and is passed the instance of enclosing scope.
0: new #32 // class com/example/Example$execute$localOp$1
3: dup
4: aload_0
5: invokespecial #36 // Method com/example/Example$execute$localOp$1."<init>":(Lcom/example/Example;)V
However, the kotlin compiler seems to generate an improper InnerClassesAttribute in this case:
InnerClasses:
public static final #2; //class com/example/Example$execute$localOp$1
It declares the member class as static which I would say is incorrect.
Looking at some test classes used in the Bnd test cases, there are also some old pre Java 7 anonymous classes also marked static in the InnerClassesAttribute.
So I made a fix to the isInnerClass test to handle these odd cases better. See https://github.com/bndtools/bnd/pull/4565. With this fix, Bnd will properly recognize kotlin’s anonymous and local classes and Bnd will also properly recognize anonymous classes made by older Java compilers.
Thanks for the test code which enabled me to understand how to make the fix.