Mehrere Lösungen in einer Classfile

This commit is contained in:
Enrico Schrödter 2015-11-25 10:23:06 +01:00
parent e4374c06fd
commit a27b4f9d3b
4 changed files with 56 additions and 16 deletions

View File

@ -7,10 +7,13 @@ import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.MethodGen;
import org.apache.commons.bcel6.generic.Type;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class MethodGenerator extends MethodGen{
@ -19,7 +22,7 @@ public class MethodGenerator extends MethodGen{
super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp);
}
public Method createMethod(ClassGenerator cg, ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type retType, Block block){
public Method createMethod(ClassGenerator cg, ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type retType, Block block, Integer typeReconstructionSetIndex){
MethodGen method = this;
DHBWInstructionFactory factory = cg.getInstructionFactory();
@ -39,10 +42,22 @@ public class MethodGenerator extends MethodGen{
//Die korrekte Signatur für die Methode anhängen. Hier sind dann auch die Parameter von RefTypes enthalten:
String paramTypesSig = "(";
for(FormalParameter p : parameter){
paramTypesSig += p.getType().getBytecodeSignature(cg);
if(p.getType() instanceof TypePlaceholder){
paramTypesSig += ((TypePlaceholder) p.getType()).getBytecodeSignature(cg, typeReconstructionSetIndex);
}else{
paramTypesSig += p.getType().getBytecodeSignature(cg);
}
Logger.getLogger("MethodGenerator").error(paramTypesSig, Section.CODEGEN);
}
paramTypesSig += ")";
String retTypeSig = retType.getBytecodeSignature(cg);
String retTypeSig = "";
if(retType instanceof TypePlaceholder){
retTypeSig = ((TypePlaceholder) retType).getBytecodeSignature(cg, typeReconstructionSetIndex);
}else{
retTypeSig = retType.getBytecodeSignature(cg);
}
method.addAttribute(factory.createSignatureAttribute(paramTypesSig+retTypeSig));
return method.getMethod();

View File

@ -78,7 +78,7 @@ public class Constructor extends Method {
//method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden)
cg.addMethod(method.createMethod(cg, getParameterList(), this.getType(), get_Block()));
cg.addMethod(method.createMethod(cg, getParameterList(), this.getType(), get_Block(), 0));
}
/**

View File

@ -746,7 +746,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
}
public void genByteCode(ClassGenerator cg) {
List<Integer> typeReconstructionSetIndexList = cg.getTypeinferenceResults().getTypeReconstructionSetIndexList(this);
List<Integer> typeReconstructionSetIndexList = cg.getTypeinferenceResults().getTypeReconstructionSetIndexList(this, cg);
for(Integer t: typeReconstructionSetIndexList){
DHBWConstantPoolGen _cp = cg.getConstantPool();
@ -769,15 +769,23 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
argumentNames[i] = parameter.getIdentifier();
i++;
}
short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public
if(this.modifiers != null && this.modifiers.includesModifier(new Static())) constants += Constants.ACC_STATIC;
Type returnType;
if(this.getType() instanceof TypePlaceholder){
returnType = cg.resolveTPH((TypePlaceholder) this.getType(), t);
}else{
returnType = this.getType();
}
//Methode generieren:
MethodGenerator method = new MethodGenerator(constants, returnType.getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp);
//Methode generieren und anfügen:
cg.addMethod(method.createMethod(cg, getParameterList(), returnType, get_Block(), t));
}
short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public
if(this.modifiers != null && this.modifiers.includesModifier(new Static())) constants += Constants.ACC_STATIC;
//Methode generieren:
MethodGenerator method = new MethodGenerator(constants, this.getType().getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp);
//Methode generieren und anfügen:
cg.addMethod(method.createMethod(cg, getParameterList(), getType(), get_Block()));
}
}

View File

@ -3,8 +3,13 @@ package de.dhbwstuttgart.typeinference;
import java.util.LinkedList;
import java.util.List;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Menge.Equal;
@ -33,7 +38,7 @@ public class TypeinferenceResults {
return typeReconstructions;
}
public List<Integer> getTypeReconstructionSetIndexList(Method method) {
public List<Integer> getTypeReconstructionSetIndexList(Method method, ClassGenerator cg) {
Menge<FormalParameter> parameters = method.parameterlist.formalparameter;
Menge<TypePlaceholder> typePlaceholders = new Menge<>();
List<Integer> result = new LinkedList<>();
@ -52,7 +57,7 @@ public class TypeinferenceResults {
reconstructionTypes[t] = getTypeOfPlaceholder(typePlaceholders.get(t), i);
}
if(!types.contains(reconstructionTypes, new TypeArrayEqual())){
if(!types.contains(reconstructionTypes, new TypeArrayEqual(cg))){
types.add(reconstructionTypes);
result.add(i);
}
@ -63,6 +68,16 @@ public class TypeinferenceResults {
}
class TypeArrayEqual implements Equal<Type[]>{
private ClassGenerator cg;
public TypeArrayEqual(ClassGenerator cg) {
super();
this.cg = cg;
}
@Override
public boolean equal(Type[] a, Type[] b) {
@ -71,7 +86,9 @@ class TypeArrayEqual implements Equal<Type[]>{
}
for(int i = 0; i < a.length; i++){
if(!a[i].equals(b[i])){
if(!a[i].getBytecodeType(cg).equals(b[i].getBytecodeType(cg))){
Logger.getLogger("TypeArrayEqual").error(a[i].toString(), Section.CODEGEN);
Logger.getLogger("TypeArrayEqual").error(b[i].toString(), Section.CODEGEN);
return false;
}
}