[
https://issues.jboss.org/browse/FORGE-678?page=com.atlassian.jira.plugin....
]
fiorenzo pizza edited comment on FORGE-678 at 10/10/12 3:38 AM:
----------------------------------------------------------------
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?
was (Author: fiorenzino):
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