AssertionError in custom handler creating a setter method.

131 views
Skip to first unread message

Gary

unread,
Dec 27, 2016, 7:09:19 PM12/27/16
to Project Lombok
Hi,

I'm hitting a strange problem with a custom Handler and java 8, and so far my attempts to get to the bottom of the problem have come up empty.

The custom annotation on the class adds a field, a setter for the field, and some annotations on the class.  Almost all of the handler works as expected, apart from the setter.  When I run the code against java8 I get the Error: "java.lang.AssertionError: Value of x -1".  In my attempt to debug the problem I tried it against java7 and it appears to work fine (i.e. delombok produces the correct source code).  From what I can tell it stems from the parameter type - at least if I change it from String to Long it produces delomboked source (though of course it fails to compile due to type mismatch).

Has anyone run into such an error, or have a hint what may be going wrong?

The handler method is as follows:

  private JCMethodDecl createNameSetterMethod(JavacNode typeNode) {
   
JavacTreeMaker maker = typeNode.getTreeMaker();
   
   
JCModifiers modifiers = maker.Modifiers(Modifier.PUBLIC);
   
List<JCTypeParameter> methodGenericTypes = List.<JCTypeParameter>nil();
   
JCExpression methodType = maker.TypeIdent(Javac.CTC_VOID);
   
Name methodName = typeNode.toName("setName");
   
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.PARAMETER), typeNode.toName("name"), JavacHandlerUtil.genJavaLangTypeRef(typeNode, "String"), null);
   
List<JCVariableDecl> methodParameters = List.of(param);
   
List<JCExpression> methodThrows = List.<JCExpression>nil();    
   
   
JCExpression nameAssignment = maker.Assign(chainDots(typeNode, "this", "name"), maker.Ident(typeNode.toName("name")));
   
JCBlock methodBody = maker.Block(0, List.<JCStatement>of(maker.Exec(nameAssignment)));
   
   
JCExpression defaultValue = null;
   
   
return maker.MethodDef(modifiers, methodName, methodType, methodGenericTypes, methodParameters, methodThrows, methodBody, defaultValue);
 
}


Which as mentioned produces the following in java7

    @java.lang.SuppressWarnings("all")
   
@javax.annotation.Generated("lombok")
   
public void setName(java.lang.String name) {
       
this.name = name;
   
}


but in java8 causes the Error below at compilation (and the same when attempting to delombok).

An exception has occurred in the compiler (1.8.0_91). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: Value of x -1
  at com.sun.tools.javac.util.Assert.error(Assert.java:133)
  at com.sun.tools.javac.util.Assert.check(Assert.java:94)
  at com.sun.tools.javac.util.Bits.incl(Bits.java:186)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.initParam(Flow.java:1858)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:1807)
  at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
  at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
  at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:404)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1382)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:1749)
  at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
  at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
  at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:404)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1382)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2446)
  at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:2429)
  at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:211)
  at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1327)
  at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1296)
  at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
  at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
  at com.sun.tools.javac.main.Main.compile(Main.java:523)
  at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
  at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
  at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:125)
  at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:171)
  at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:886)
  at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
  at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
  at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
  at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
  at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
  at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
  at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
  at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
  at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
  at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
  at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
  at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
  at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
  at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
  at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
  at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
  at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
  at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

Any help or suggestion would be greatly appreciated.

Best regards,
Gary

Gary

unread,
Dec 29, 2016, 11:09:23 AM12/29/16
to Project Lombok
A little more investigation and the java7/8 distinction appears to be a red herring - the code is delomboked whenever there is an error.  The root cause is that the VarSymbol of the parameter has an address of "-1" and hence the check fails.  Why this is the case I am still unsure, and all my attempts to "correctly" define the parameter have so far failed (e.g. via a field declaration, or directly with names and types)

Gary

unread,
Dec 29, 2016, 5:12:13 PM12/29/16
to Project Lombok
So in case anyone else has this issue, I appear to have got it working by wrapping the MethodDef call with JavacHandlerUtil.recursiveSetGeneratedBy.  Exactly what adding these annotations to the method does in order for it to work I don't yet know :/

For completeness, the example method from earlier is shown here with the change... 

  private JCMethodDecl createNameSetterMethod(JavacNode typeNode) {
   
JavacTreeMaker maker = typeNode.getTreeMaker();
   
   
JCModifiers modifiers = maker.Modifiers(Modifier.PUBLIC);
   
List<JCTypeParameter> methodGenericTypes = List.<JCTypeParameter>nil();
   
JCExpression methodType = maker.TypeIdent(Javac.CTC_VOID);
   
Name methodName = typeNode.toName("setName");
   
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.PARAMETER), typeNode.toName("name"), JavacHandlerUtil.genJavaLangTypeRef(typeNode, "String"), null);
   
List<JCVariableDecl> methodParameters = List.of(param);
   
List<JCExpression> methodThrows = List.<JCExpression>nil();
   
   
JCExpression nameAssignment = maker.Assign(chainDots(typeNode, "this", "name"), maker.Ident(typeNode.toName("name")));
   
JCBlock methodBody = maker.Block(0, List.<JCStatement>of(maker.Exec(nameAssignment)));
   
   
JCExpression defaultValue = null;

   
   
return recursiveSetGeneratedBy(maker.MethodDef(modifiers, methodName, methodType, methodGenericTypes, methodParameters, methodThrows, methodBody, defaultValue), typeNode.get(), typeNode.getContext());
 
}

  
resulting in the following delomboked code as expected...
Reply all
Reply to author
Forward
0 new messages