1

I've been working on a processor that injects an inner class inside a method, and I'm having a lot of trouble figuring out just how to generate the class and accompanying object initialization without incurring auto-generation of an incorrect fully-qualified name.

For example, I've been processing stuff like: I've been making a new class:

CtClass internal = getFactory().Core().createClass();

and then inserting it before an element within a method

element.insertBefore(internal);

but when I make an initialization statement:

CtConstructorCall call = getFactory().Core().createConstructorCall();
call.setType(internal);
internal.insertAfter(call);

I get a call that looks like:

Main.internal initializedInternalObject = new Main.internal();

Where Main is the name of the overall class that everything is inside, even though internal is declared only inside a specific method. I've tried using getFactory().Class().create() method for internal classes, but that method only seems to be targeted toward classes nested within classes, as opposed to classes delcared within methods.

Am I doing something wrong with the class declaration? Am I just running into a limitation of spoon's ability to generate internal classes? Any suggestions?

Thanks everyone!

Luke
  • 33
  • 5

2 Answers2

0

One possible solution is to prefix the internal class name by a digit.

Does this work?

Don't hesitate to use Github issues for reporting strange behaviors.

Martin Monperrus
  • 1,845
  • 2
  • 19
  • 28
  • Even after prefixing the internal class name with a numeral, it seems that Spoon doesn't really like to generate local classes _within_ a method where the fully-qualified name and simple name would be identical. As far as I know it is usally bad practice to make a named class within the scope of a method anyhow, but for my specific project it is necessary. Luckily, though, it's pretty simple to just use code snippet expressions to generate expressions involving the inner class type or constructor call, so it doesn't seem like a big deal. – Luke Aug 15 '16 at 03:03
  • As and aside, the behavior of Spoon in this case doesn't seems "strange" so much as lacking a feature, but I have made a note of the lack of support for internal classes within methods on the [issues](https://github.com/INRIA/spoon/issues/) page. – Luke Aug 15 '16 at 03:06
0

Althought it is somewhat of a hack, code snippet expressions allow for manual overriding of expressions involving the type name and constructor calls of a given internal class. For example:

String constructorCallSnippet = 
    "new " + classType.toString() + "(" 
    + String.join(", ", args.stream().map(a -> a.toString()).collect(toList()))
    + ")";
CtExpression constructorCall =
    getFactory().Code().createCodeSnippetExpression(constructorCallSnippet);
Luke
  • 33
  • 5