[forge-issues] [JBoss JIRA] (FORGE-678) forge-parser-java: JavaClassImpl with generic super type produces wrong code
fiorenzo pizza (JIRA)
jira-events at lists.jboss.org
Tue Oct 9 20:32:02 EDT 2012
[ https://issues.jboss.org/browse/FORGE-678?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12725151#comment-12725151 ]
fiorenzo pizza commented on FORGE-678:
--------------------------------------
THIS IS A LITTLE BRAINSTORMING AFTER MY RESEARCH...
if my assumptions are correct, I WILL CREATE A BRANCH CODE FOR A PULL REQUEST.
-----------------------------------------
-----------------------------------------
After a lot of search (for me, AST is very badly documented!!), i created the following use case.
My goal is to create this java class:
-----------------------------------------
package test1;
public class E<T> extends F<T> {
public boolean foo(){
}
}
-----------------------------------------
-----------------------------------------
I created a java project without forge inside:
-----------------------------------------
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeParameter;
public class ASTClassCreatorWithGenericsExtensions
{
public static void main(String[] args)
{
AST ast = AST.newAST(AST.JLS3);
CompilationUnit unit = ast.newCompilationUnit();
PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
packageDeclaration.setName(ast.newSimpleName("test1"));
unit.setPackage(packageDeclaration);
TypeParameter tp2 = ast.newTypeParameter();
tp2.setName(ast.newSimpleName("T"));
TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("E"));
td.typeParameters().add(tp2);
ParameterizedType PT1 = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("F")));
PT1.typeArguments().add(ast.newSimpleType(ast.newSimpleName("T")));
td.setSuperclassType(PT1);
Modifier mod = ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD);
td.modifiers().add(mod);
unit.types().add(td);
MethodDeclaration md = ast.newMethodDeclaration();
md.setName(ast.newSimpleName("foo"));
md.setReturnType2(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
mod = ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD);
md.modifiers().add(mod);
Block block = ast.newBlock();
md.setBody(block);
td.bodyDeclarations().add(md);
System.out.println(unit);
}
}
-----------------------------------------
-----------------------------------------
-----------------------------------------
using that example code, we should modify the method setSuperType in the class org.jboss.forge.parser.spi.JavaParserImpl :
-----------------------------------------
@Override
public JavaClass setSuperType(final String type)
{
if (Types.isGeneric(type))
{
String typeD = Types.stripGenerics(type);
String typeP = Types.getGenericsTypeArgument(type);
org.eclipse.jdt.core.dom.ParameterizedType pt = body.getAST().newParameterizedType(
body.getAST().newSimpleType(body.getAST().newSimpleName(typeD)));
pt.typeArguments().add(body.getAST().newSimpleType(body.getAST().newSimpleName(typeP)));
getBodyDeclaration().setStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, pt);
if (!hasImport(typeD) && Types.isQualified(typeD))
{
addImport(typeD);
}
if (!hasImport(typeP) && Types.isQualified(typeP))
{
addImport(typeP);
}
}
else
{
SimpleType simpleType = body.getAST().newSimpleType(body.getAST().newSimpleName(Types.toSimpleName(type)));
getBodyDeclaration().setStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, simpleType);
if (!hasImport(type) && Types.isQualified(type))
{
addImport(type);
}
}
return this;
}
-------------------------------------------------------
I also added to org.jboss.forge.parser.java.util.Types this new method:
public static String getGenericsTypeArgument(final String type)
{
return getGenerics(type).replaceAll("<", "").replaceAll(">", "");
}
-------------------------------------------------------
What do you think about my solution?
> forge-parser-java: JavaClassImpl with generic super type produces wrong code
> -----------------------------------------------------------------------------
>
> Key: FORGE-678
> URL: https://issues.jboss.org/browse/FORGE-678
> Project: Forge
> Issue Type: Bug
> Components: Parsers / File Manipulation
> Affects Versions: 1.0.6.Final
> Reporter: fiorenzo pizza
> Labels: annoying
>
> forge doesn't support correctly generics.
> some use case, improperly parsed:
> JavaClass c1 = JavaParser.parse(JavaClass.class, "package it.coopservice.test; public class Bar<T> {}");
> JavaClass javaClass = JavaParser.create(JavaClass.class);
> javaClass.setName("TBarTest");
> javaClass.setSuperType(c1);
> javaClass.setPackage("it.coopservice.test");
> javaClass.addImport("it.coopservice.test.Bar");
> produces:
> public class TBarTest extends Bar{}
> and this:
> JavaClass c0 = JavaParser.parse(JavaClass.class, "package it.coopservice.test; public class Foo {}");
> JavaClass c1 = JavaParser.parse(JavaClass.class, "package it.coopservice.test; public class Bar<Foo> {}");
> JavaClass javaClass = JavaParser.create(JavaClass.class);
> javaClass.setName("FooBarDirectTest");
> javaClass.setPackage("it.coopservice.test");
> javaClass.addImport("it.coopservice.test.Bar");
> javaClass.addImport("it.coopservice.test.Foo");
> javaClass.setSuperType("Bar<Foo>");
> produces:
> java.lang.IllegalArgumentException
> my complete test code and output:
> https://gist.github.com/3746475
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the forge-issues
mailing list