diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 5a8735c1..49c31e45 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -85,6 +85,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; +import javassist.compiler.SyntaxError; public class SyntaxTreeGenerator { private JavaClassRegistry reg; @@ -219,22 +220,15 @@ public class SyntaxTreeGenerator { implementedInterfaces.addAll(convert(ctx.typeList(0), generics)); } // Ist Bit für 'sealed'-Modifier gesetzt - if ((modifiers & 4096) != 0) { - switch (ctx.typeList().size()) { - case 1: { - permittedSubtypes.addAll(convert(ctx.typeList(0), generics)); - break; - } - case 2: { - permittedSubtypes.addAll(convert(ctx.typeList(1), generics)); - break; - } - default: { - break; - } - } + if ((modifiers & 4096) != 0 && !Objects.isNull(ctx.PERMITS())) { + // permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration') + permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics)); + } else { + // falls sealed modifier ohne 'permits'-List oder umgekehrt + throw new NotImplementedException("Invalid sealed class declaration"); } - return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); + return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset); + } private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) { @@ -388,7 +382,16 @@ public class SyntaxTreeGenerator { if (!Objects.isNull(ctx.EXTENDS())) { extendedInterfaces.addAll(convert(ctx.typeList(0), generics)); } - return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, ctx.getStart()); + List permittedSubtypes = new ArrayList<>(); + // Ist Bit für 'sealed'-Modifier gesetzt + if ((modifiers & 4096) != 0 && !Objects.isNull(ctx.PERMITS())) { + // permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration') + permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics)); + } else { + // falls sealed modifier ohne 'permits'-List oder umgekehrt + throw new NotImplementedException("Invalid sealed class declaration"); + } + return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart()); } private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) { diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index c3562f7f..8b668738 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -2,7 +2,6 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.statement.*; -import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.type.*; import java.util.Iterator; @@ -274,4 +273,47 @@ public abstract class AbstractASTWalker implements ASTVisitor { public void visit(SuperCall superCall) { this.visit((MethodCall) superCall); } + + @Override + public void visit(Switch switchStmt) { + switchStmt.getSwitch().accept(this); + switchStmt.getBlocks().stream().forEach((switchBlock) -> { + switchBlock.accept(this); + }); + } + + @Override + public void visit(SwitchBlock switchBlock) { + switchBlock.getLabels().stream().forEach((label) -> { + label.accept(this); + }); + switchBlock.getStatements().stream().forEach((stmt) -> { + stmt.accept(this); + }); + } + + @Override + public void visit(SwitchLabel switchLabel) { + switchLabel.getExpression().accept(this); + } + + @Override + public void visit(Yield aYield) { + aYield.accept(this); + } + + @Override + public void visit(Pattern aPattern) { + + } + + @Override + public void visit(RecordPattern aRecordPattern) { + + } + + @Override + public void visit(GuardedPattern aGuardedPattern) { + + } } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 459ae46d..5e9b8d8f 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -24,96 +24,95 @@ import java.util.Optional; /** * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces */ -public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ - private Boolean methodAdded = false; //wird benoetigt bei in JavaTXCompiler.getConstraints() +public class ClassOrInterface extends SyntaxTreeNode implements TypeScope { + private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints() protected int modifiers; protected JavaClassName name; private List fields = new ArrayList<>(); - private Optional fieldInitializations; //PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen + private Optional fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen private List methods = new ArrayList<>(); private GenericDeclarationList genericClassParameters; private RefType superClass; protected boolean isInterface; private List implementedInterfaces; + private List permittedSubtypes; private List constructors; - - public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, List methods, List constructors, GenericDeclarationList genericClassParameters, - RefType superClass, Boolean isInterface, List implementedInterfaces, Token offset){ + public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, List permittedSubtypes, Token offset) { super(offset); - if(isInterface && !Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE; - this.modifiers = modifiers; - this.name = name; - this.fields = fielddecl; - this.fieldInitializations= fieldInitializations; + if (isInterface && !Modifier.isInterface(modifiers)) + modifiers += Modifier.INTERFACE; + this.modifiers = modifiers; + this.name = name; + this.fields = fielddecl; + this.fieldInitializations = fieldInitializations; this.genericClassParameters = genericClassParameters; - this.superClass = superClass; + this.superClass = superClass; this.isInterface = isInterface; - this.implementedInterfaces = implementedInterfaces; + this.implementedInterfaces = implementedInterfaces; + this.permittedSubtypes = permittedSubtypes; this.methods = methods; this.constructors = constructors; } - - /* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte - * alle anderen Datenobjekte werden nur kopiert. + + /* + * erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte alle anderen Datenobjekte werden nur kopiert. */ - public ClassOrInterface(ClassOrInterface cl){ - super(cl.getOffset()); - this.modifiers = cl.modifiers; - this.name = cl.name; - this.fields = new ArrayList<>(cl.fields); - this.fieldInitializations= cl.fieldInitializations; - this.genericClassParameters = cl.genericClassParameters; - this.superClass = cl.superClass; - this.isInterface = cl.isInterface; - this.implementedInterfaces = cl.implementedInterfaces; - this.methods = new ArrayList<>(cl.methods); - this.constructors = new ArrayList<>(cl.constructors); + public ClassOrInterface(ClassOrInterface cl) { + super(cl.getOffset()); + this.modifiers = cl.modifiers; + this.name = cl.name; + this.fields = new ArrayList<>(cl.fields); + this.fieldInitializations = cl.fieldInitializations; + this.genericClassParameters = cl.genericClassParameters; + this.superClass = cl.superClass; + this.isInterface = cl.isInterface; + this.implementedInterfaces = cl.implementedInterfaces; + this.methods = new ArrayList<>(cl.methods); + this.constructors = new ArrayList<>(cl.constructors); } - - //Gets if it is added + + // Gets if it is added public Boolean areMethodsAdded() { - return methodAdded; + return methodAdded; } - - //Sets that it is added + + // Sets that it is added public void setMethodsAdded() { - methodAdded = true; + methodAdded = true; } - + // Gets class name - public JavaClassName getClassName(){ + public JavaClassName getClassName() { return this.name; } - + // Get modifiers - public int getModifiers(){ + public int getModifiers() { return this.modifiers; } - public List getFieldDecl(){ + public List getFieldDecl() { return this.fields; } - - public Optional getfieldInitializations(){ - return this.fieldInitializations; - } - - public List getMethods(){ + + public Optional getfieldInitializations() { + return this.fieldInitializations; + } + + public List getMethods() { return this.methods; } /* - public RefType getType() { - return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); - } - */ - //TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt - public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ - //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern + * public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); } + */ + // TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt + public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass, Token offset) { + // Hier wird immer ein generischer Typ generiert, also mit Type placeholdern List params = new ArrayList<>(); - for(GenericTypeVar genericTypeVar : genericsOfClass){ - //params.add(genericTypeVar.getTypePlaceholder()); + for (GenericTypeVar genericTypeVar : genericsOfClass) { + // params.add(genericTypeVar.getTypePlaceholder()); params.add(TypePlaceholder.fresh(offset)); } return new RefType(name, params, offset); @@ -123,18 +122,18 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ * * @return die aktuelle Klasse als RefType */ - public RefType generateTypeOfThisClass(){ - List params = new ArrayList<>(); - for(GenericTypeVar genericTypeVar : this.getGenerics()){ - //params.add(genericTypeVar.getTypePlaceholder()); - params.add(new GenericRefType(genericTypeVar.getName(), new NullToken())); - } - return new RefType(name, params, new NullToken()); - } + public RefType generateTypeOfThisClass() { + List params = new ArrayList<>(); + for (GenericTypeVar genericTypeVar : this.getGenerics()) { + // params.add(genericTypeVar.getTypePlaceholder()); + params.add(new GenericRefType(genericTypeVar.getName(), new NullToken())); + } + return new RefType(name, params, new NullToken()); + } + /** - * Die Superklasse im Kontext dieser ClassOrInterface - * Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind - */ + * Die Superklasse im Kontext dieser ClassOrInterface Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind + */ public RefType getSuperClass() { return superClass; } @@ -160,8 +159,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ public Collection getSuperInterfaces() { return implementedInterfaces; } - + public String toString() { - return this.name.toString() + this.genericClassParameters.toString(); + return this.name.toString() + this.genericClassParameters.toString(); } } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java b/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java index 46f89f19..1b147306 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.syntaxtree; +import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -11,6 +12,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefType; public class Record extends ClassOrInterface { public Record(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, Token offset) { - super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); + super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset); } } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index f33fa76a..d0faf486 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -29,13 +29,11 @@ import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureVisitor; /** - * Anmerkung: - * Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen, - * dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen. + * Anmerkung: Die ASTFactory Methoden, welche ASTBäume aus java.lang.Class Objekten generieren, können davon ausgehen, dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen. */ public class ASTFactory { - public static ClassOrInterface createClass(java.lang.Class jreClass){ + public static ClassOrInterface createClass(java.lang.Class jreClass) { // TODO Inner classes @@ -82,7 +80,7 @@ public class ASTFactory { } }; - classReader.accept(classVisitor, new Attribute[]{new JavaTXSignatureAttribute()}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + classReader.accept(classVisitor, new Attribute[] { new JavaTXSignatureAttribute() }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); classSignature = classVisitor.classSignature; } } catch (IOException e) { @@ -92,7 +90,7 @@ public class ASTFactory { JavaClassName name = new JavaClassName(jreClass.getName()); List methoden = new ArrayList<>(); List konstruktoren = new ArrayList<>(); - for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){ + for (java.lang.reflect.Constructor constructor : jreClass.getConstructors()) { var signature = methodSignatures.get(new Pair<>(constructor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(constructor))); createConstructor(constructor, signature, jreClass).map(c -> konstruktoren.add(c)); } @@ -100,65 +98,72 @@ public class ASTFactory { Set allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods())); Set allInheritedMethods = new HashSet<>(allMethods); allInheritedMethods.removeAll(allDeclaredMethods); - for(java.lang.reflect.Method method : allDeclaredMethods){ + for (java.lang.reflect.Method method : allDeclaredMethods) { var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method))); methoden.add(createMethod(method, signature, jreClass, false)); } - for(java.lang.reflect.Method method : allInheritedMethods){ + for (java.lang.reflect.Method method : allInheritedMethods) { var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method))); methoden.add(createMethod(method, signature, jreClass, true)); } List felder = new ArrayList<>(); - for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){ + for (java.lang.reflect.Field field : jreClass.getDeclaredFields()) { felder.add(createField(field, name)); } int modifier = jreClass.getModifiers(); boolean isInterface = jreClass.isInterface(); - //see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class + // see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class ParameterizedType parameterSuperClass = null; Type tempSuperClass = jreClass.getGenericSuperclass(); - if(tempSuperClass != null && tempSuperClass instanceof ParameterizedType) + if (tempSuperClass != null && tempSuperClass instanceof ParameterizedType) parameterSuperClass = (ParameterizedType) tempSuperClass; java.lang.Class superjreClass = jreClass.getSuperclass(); RefType superClass; - if(parameterSuperClass != null){ + if (parameterSuperClass != null) { superClass = (RefType) createType(parameterSuperClass); - }else if(superjreClass != null){ + } else if (superjreClass != null) { superClass = (RefType) createType(superjreClass); - }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) + } else {// Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) superClass = (RefType) createType(java.lang.Object.class); } List implementedInterfaces = new ArrayList<>(); - for(Type jreInterface : jreClass.getGenericInterfaces()){ + for (Type jreInterface : jreClass.getGenericInterfaces()) { implementedInterfaces.add((RefType) createType(jreInterface)); } + List permittedSubtypes = new ArrayList<>(); + if (jreClass.isSealed()) { + for (Class subclass : jreClass.getPermittedSubclasses()) { + permittedSubtypes.add((RefType) createType(subclass)); + } + } - GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature); + GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null, classSignature); - Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde + Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde - return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */,methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset); + return new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, methoden, konstruktoren, genericDeclarationList, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset); } private static Field createField(java.lang.reflect.Field field, JavaClassName jreClass) { return new Field(field.getName(), createType(field.getGenericType()), field.getModifiers(), new NullToken()); } - //private static RefType createType(Class classType) { - // return createClass(classType).getType(); - //} + // private static RefType createType(Class classType) { + // return createClass(classType).getType(); + // } - private static Optional createConstructor(Constructor constructor, String signature, Class inClass) { + private static Optional createConstructor(Constructor constructor, String signature, Class inClass) { String name = constructor.getName(); RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass); Parameter[] jreParams = constructor.getParameters(); Type[] jreGenericParams = constructor.getGenericParameterTypes(); List params = new ArrayList<>(); int i = 0; - for(Type jreParam : jreGenericParams){ - if (jreParam == null) continue; + for (Type jreParam : jreGenericParams) { + if (jreParam == null) + continue; RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam); - params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken())); + params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken())); i++; } ParameterList parameterList = new ParameterList(params, new NullToken()); @@ -167,20 +172,20 @@ public class ASTFactory { Token offset = new NullToken(); int modifier = constructor.getModifiers(); - if(inClass.equals(java.lang.Object.class)){ + if (inClass.equals(java.lang.Object.class)) { return Optional.empty(); } - return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */)); + return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name, returnType, parameterList, block, gtvDeclarations, offset /* , new ArrayList<>() geloescht PL 2018-11-24 */)); } - public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited){ + public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited) { String name = jreMethod.getName(); RefTypeOrTPHOrWildcardOrGeneric returnType; Type jreRetType; - if(jreMethod.getGenericReturnType()!=null){ + if (jreMethod.getGenericReturnType() != null) { jreRetType = jreMethod.getGenericReturnType(); - }else{ + } else { jreRetType = jreMethod.getReturnType(); } returnType = createType(jreRetType); @@ -188,24 +193,25 @@ public class ASTFactory { Type[] jreGenericParams = jreMethod.getGenericParameterTypes(); List params = new ArrayList<>(); int i = 0; - for(Type jreParam : jreGenericParams){ - if (jreParam == null) continue; + for (Type jreParam : jreGenericParams) { + if (jreParam == null) + continue; RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam); - params.add(new FormalParameter(jreParams[i].getName(),paramType, new NullToken())); + params.add(new FormalParameter(jreParams[i].getName(), paramType, new NullToken())); i++; } ParameterList parameterList = new ParameterList(params, new NullToken()); Block block = new Block(new ArrayList(), new NullToken()); - GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature); + GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName(), signature); Token offset = new NullToken(); - return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited); + return new Method(jreMethod.getModifiers(), name, returnType, parameterList, block, gtvDeclarations, offset, isInherited); } public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName, String signature) { if (signature == null) { List gtvs = new ArrayList<>(); - for(TypeVariable jreTV : typeParameters){ + for (TypeVariable jreTV : typeParameters) { de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName); gtvs.add(gtv); } @@ -217,7 +223,8 @@ public class ASTFactory { } public static GenericDeclarationList createGenerics(String signature) { - if (signature == null) return new GenericDeclarationList(new ArrayList<>(), new NullToken()); + if (signature == null) + return new GenericDeclarationList(new ArrayList<>(), new NullToken()); var gtvs = new ArrayList(); var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) { @@ -226,7 +233,8 @@ public class ASTFactory { final Stack classTypes = new Stack<>(); // All hail the mighty visitor pattern - final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) {}; + final SignatureVisitor doNothing = new SignatureVisitor(Opcodes.ASM7) { + }; char wildcard = '='; @@ -334,61 +342,61 @@ public class ASTFactory { return new GenericDeclarationList(gtvs, new NullToken()); } - private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type){ - if(type == null || type.getTypeName().equals("void")){ + private static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type) { + if (type == null || type.getTypeName().equals("void")) { return new Void(new NullToken()); - }else if(type.getTypeName().equals("int")){ + } else if (type.getTypeName().equals("int")) { return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("byte")){ + } else if (type.getTypeName().equals("byte")) { return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("boolean")){ + } else if (type.getTypeName().equals("boolean")) { return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("char")){ + } else if (type.getTypeName().equals("char")) { return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("short")){ + } else if (type.getTypeName().equals("short")) { return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("double")){ + } else if (type.getTypeName().equals("double")) { return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken()); - }else if(type.getTypeName().equals("long")){ + } else if (type.getTypeName().equals("long")) { return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken()); - }else{ - if(type instanceof TypeVariable){ - //GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()" + } else { + if (type instanceof TypeVariable) { + // GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()" return new GenericRefType(type.getTypeName(), new NullToken()); } List params = new ArrayList<>(); - if(type instanceof ParameterizedType){ - for(Type t : ((ParameterizedType)type).getActualTypeArguments()){ + if (type instanceof ParameterizedType) { + for (Type t : ((ParameterizedType) type).getActualTypeArguments()) { params.add(createType(t)); } } String name = type.getTypeName(); - if(name.contains("<")){ //Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type - //Diese entfernen: + if (name.contains("<")) { // Komischer fix. Type von Generischen Typen kann die Generics im Namen enthalten Type + // Diese entfernen: name = name.split("<")[0]; } - if(type instanceof java.lang.reflect.WildcardType){ + if (type instanceof java.lang.reflect.WildcardType) { java.lang.reflect.WildcardType wildcardType = (java.lang.reflect.WildcardType) type; - if(wildcardType.getLowerBounds().length > 0){ + if (wildcardType.getLowerBounds().length > 0) { return new SuperWildcardType(createType(wildcardType.getLowerBounds()[0]), new NullToken()); - }else if(wildcardType.getUpperBounds().length > 0){ + } else if (wildcardType.getUpperBounds().length > 0) { return new ExtendsWildcardType(createType(wildcardType.getUpperBounds()[0]), new NullToken()); - }else{//Es handelt sich um den '?'-Typ: + } else {// Es handelt sich um den '?'-Typ: return new ExtendsWildcardType(createObjectType(), new NullToken()); } - }else{ + } else { RefType ret = new RefType(new JavaClassName(name), params, new NullToken()); return ret; } } } - public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){ + public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod) { JavaClassName parentClass = new JavaClassName(context.getName()); List genericBounds = new ArrayList<>(); java.lang.reflect.Type[] bounds = jreTypeVar.getBounds(); - if(bounds.length > 0){ - for(java.lang.reflect.Type bound : bounds){ + if (bounds.length > 0) { + for (java.lang.reflect.Type bound : bounds) { genericBounds.add(createType(bound)); } } @@ -403,49 +411,27 @@ public class ASTFactory { return new RefType(createClass(Object.class).getClassName(), new NullToken()); } - /* - public Constructor createEmptyConstructor(Class parent){ - Block block = new Block(); - block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); - block.statements.add(new SuperCall(block)); - - return ASTFactory.createConstructor(parent, new ParameterList(), block); - } - - public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){ - block.parserPostProcessing(superClass); - - Method method = ASTFactory.createMethod("", paralist, block, superClass); - method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); - - return new Constructor(method, superClass); - } - - public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) { - // TODO bytecode createClass - //String name, RefType superClass, Modifiers modifiers, Menge supertypeGenPara - Class generatedClass = new Class(className, type, modifiers, supertypeGenPara); - generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass)); - - generatedClass.parserPostProcessing(parent); - - return generatedClass; - } - - public static Class createObject(){ - return createClass(java.lang.Object.class); - } - - public static Class createInterface(String className, RefType superClass, Modifiers modifiers, - Menge supertypeGenPara, SourceFile parent){ - Class generatedClass = new Class(new JavaClassName(className), new ArrayList(), new ArrayList(), modifiers, - true, superClass, new ArrayList(), new GenericDeclarationList(), -1); - generatedClass.parserPostProcessing(parent); - return generatedClass; - } - - public static RefType createObjectType(){ - return createObjectClass().getType(); - } - */ + /* + * public Constructor createEmptyConstructor(Class parent){ Block block = new Block(); block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); block.statements.add(new SuperCall(block)); + * + * return ASTFactory.createConstructor(parent, new ParameterList(), block); } + * + * public static Constructor createConstructor(Class superClass, ParameterList paralist, Block block){ block.parserPostProcessing(superClass); + * + * Method method = ASTFactory.createMethod("", paralist, block, superClass); method.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); + * + * return new Constructor(method, superClass); } + * + * public static Class createClass(String className, RefType type, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent) { // TODO bytecode createClass //String name, RefType superClass, Modifiers modifiers, Menge supertypeGenPara Class generatedClass = new Class(className, type, modifiers, supertypeGenPara); generatedClass.addField(ASTFactory.createEmptyConstructor(generatedClass)); + * + * generatedClass.parserPostProcessing(parent); + * + * return generatedClass; } + * + * public static Class createObject(){ return createClass(java.lang.Object.class); } + * + * public static Class createInterface(String className, RefType superClass, Modifiers modifiers, Menge supertypeGenPara, SourceFile parent){ Class generatedClass = new Class(new JavaClassName(className), new ArrayList(), new ArrayList(), modifiers, true, superClass, new ArrayList(), new GenericDeclarationList(), -1); generatedClass.parserPostProcessing(parent); return generatedClass; } + * + * public static RefType createObjectType(){ return createObjectClass().getType(); } + */ } \ No newline at end of file diff --git a/src/test/java/constraintSimplify/FamilyOfGenerics.java b/src/test/java/constraintSimplify/FamilyOfGenerics.java index c7b97773..54681cac 100644 --- a/src/test/java/constraintSimplify/FamilyOfGenerics.java +++ b/src/test/java/constraintSimplify/FamilyOfGenerics.java @@ -14,46 +14,40 @@ import java.util.HashSet; import java.util.Optional; public class FamilyOfGenerics { - + @Test public void generateBC() throws Exception { - /*SourceFile sf = generateAST(); - PositionFinder.getPositionOfTPH(sf, null); - TPHExtractor tphExtractor = new TPHExtractor(); - List results = new ArrayList(); - GeneratedGenericsFinder generatedGenericsFinder = new GeneratedGenericsFinder(sf, results);*/ + /* + * SourceFile sf = generateAST(); PositionFinder.getPositionOfTPH(sf, null); TPHExtractor tphExtractor = new TPHExtractor(); List results = new ArrayList(); GeneratedGenericsFinder generatedGenericsFinder = new GeneratedGenericsFinder(sf, results); + */ } - public static SourceFile generateAST(){ + public static SourceFile generateAST() { ArrayList classes = new ArrayList<>(); ArrayList fields = new ArrayList<>(); ArrayList methods = new ArrayList<>(); fields.add(generateField("fld1")); - String[] paramNames = {"a"}; + String[] paramNames = { "a" }; methods.add(generateMethod("testMethode", paramNames)); - classes.add(new ClassOrInterface(Modifier.PUBLIC, new JavaClassName("Test"), fields, Optional.empty(), methods, - new ArrayList<>(), generateEmptyGenericDeclList(), - new RefType(new JavaClassName("java.lang.Object"), new NullToken()), - false, new ArrayList<>(), new NullToken())); + classes.add(new ClassOrInterface(Modifier.PUBLIC, new JavaClassName("Test"), fields, Optional.empty(), methods, new ArrayList<>(), generateEmptyGenericDeclList(), new RefType(new JavaClassName("java.lang.Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken())); return new SourceFile("Test.jav", classes, new HashSet<>()); } - public static Method generateMethod(String methodName, String[] paramNames){ + public static Method generateMethod(String methodName, String[] paramNames) { ArrayList parameters = new ArrayList<>(); - for(String str: paramNames) { + for (String str : paramNames) { FormalParameter fp = new FormalParameter(str, TypePlaceholder.fresh(new NullToken()), new NullToken()); parameters.add(fp); } ParameterList parameterList = new ParameterList(parameters, new NullToken()); - return new Method(Modifier.PUBLIC, methodName, TypePlaceholder.fresh(new NullToken()), parameterList, - new Block(new ArrayList<>(), new NullToken()), generateEmptyGenericDeclList(), new NullToken()); + return new Method(Modifier.PUBLIC, methodName, TypePlaceholder.fresh(new NullToken()), parameterList, new Block(new ArrayList<>(), new NullToken()), generateEmptyGenericDeclList(), new NullToken()); } - public static GenericDeclarationList generateEmptyGenericDeclList(){ + public static GenericDeclarationList generateEmptyGenericDeclList() { return new GenericDeclarationList(new ArrayList<>(), new NullToken()); } diff --git a/src/test/java/targetast/ASTToTypedTargetAST.java b/src/test/java/targetast/ASTToTypedTargetAST.java index ecc070e1..c6e3d394 100644 --- a/src/test/java/targetast/ASTToTypedTargetAST.java +++ b/src/test/java/targetast/ASTToTypedTargetAST.java @@ -25,7 +25,7 @@ public class ASTToTypedTargetAST { @Test public void emptyClass() { - ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new NullToken()); + ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken()); ResultSet emptyResultSet = new ResultSet(new HashSet<>()); TargetClass emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass); assert emptyTargetClass.getName().equals("EmptyClass");