- Verhindern von der Generierung von doppelte Methoden

This commit is contained in:
Enrico Schrödter 2016-03-20 18:55:36 +01:00
parent 4681b03838
commit c80dc162d9
9 changed files with 85 additions and 198 deletions

View File

@ -7,6 +7,8 @@ import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
@ -72,6 +74,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
protected UsedId pkgName; protected UsedId pkgName;
protected Modifiers modifiers; protected Modifiers modifiers;
protected String name; protected String name;
private List<String> methodSignaturesAndNames = new LinkedList<>();
/** /**
* *
@ -106,7 +109,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
} }
//Zuerst die Methoden und Felder abarbeiten: //Zuerst die Methoden und Felder abarbeiten:
for(Method m : methods){ for(Method m : methods){
m.genByteCode(_cg); m.genByteCode(_cg, this);
} }
InstructionList fieldInitializations = new InstructionList(); InstructionList fieldInitializations = new InstructionList();
for(FieldDeclaration f : fieldDeclarations){ for(FieldDeclaration f : fieldDeclarations){
@ -1039,6 +1042,14 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
public boolean isInterface(){ public boolean isInterface(){
return false; return false;
} }
protected boolean methodExists(String nameAndSignature) {
return methodSignaturesAndNames.contains(nameAndSignature);
}
protected void addMethod(String nameAndSignature) {
methodSignaturesAndNames.add(nameAndSignature);
}
/* /*
private Collection<? extends ByteCodeResult> getGenericClasses() { private Collection<? extends ByteCodeResult> getGenericClasses() {

View File

@ -98,7 +98,7 @@ public class Constructor extends Method {
} }
@Override @Override
public void genByteCode(ClassGenerator cg) { public void genByteCode(ClassGenerator cg, Class classObj) {
this.genByteCode(cg, new InstructionList()); this.genByteCode(cg, new InstructionList());
} }
// super statement muss drin sein // super statement muss drin sein

View File

@ -1,6 +1,7 @@
// ino.module.Method.8564.package // ino.module.Method.8564.package
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import java.util.Arrays;
// ino.end // ino.end
// ino.module.Method.8564.import // ino.module.Method.8564.import
import java.util.Enumeration; import java.util.Enumeration;
@ -465,39 +466,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
} }
@Override @Override
public void wandleRefTypeAttributes2GenericAttributes( public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> classParalist) {
Menge<Type> classParalist) {
/*
* Menge<Type> paralist = new Menge<Type>();//Mit den Generischen Typen
* der Methode paralist.addAll(classParalist);
* paralist.addAll(this.genericMethodParameters);
*
* // Zuerst Returntype untersuchen Type returnType=getType(); Type
* pendantReturnType = null; if(returnType instanceof
* RefType)pendantReturnType =
* ((RefType)returnType).findGenericType(paralist, new
* Menge<GenericTypeVar>()); //GenericTypeVar
* pendantReturnType=ClassHelper.findGenericType(returnType,
* paralist,genericMethodParameters); if(pendantReturnType!=null){
* //Wenn generisch, dann modifizieren setReturnType(pendantReturnType);
* }
*
* // Dann parameterlist untersuchen for(int
* par=0;par<getParameterCount();par++){ FormalParameter
* fp=parameterlist.formalparameter.get(par); Type fpType=fp.getType();
* // Nur wenn es sich um ein RefType-Field handelt Type pendantPara =
* null; if(fpType instanceof RefType)pendantPara =
* ((RefType)fpType).findGenericType(paralist, new
* Menge<GenericTypeVar>()); //GenericTypeVar
* pendantPara=ClassHelper.findGenericType
* (fpType,paralist,genericMethodParameters); if(pendantPara!=null){
* //Wenn generisch, dann modifizieren fp.setType(pendantPara); } }
*
* // Zuletzt alle Lokalen Variablendeklarationen durchgehen
* if(block!=null){
* block.wandleRefTypeAttributes2GenericAttributes(paralist
* ,genericMethodParameters); }
*/
} }
public void set_Method_Name(String string) { public void set_Method_Name(String string) {
@ -520,30 +489,11 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
// TypeCheck, falls es sich um einen RefType handelt: // TypeCheck, falls es sich um einen RefType handelt:
this.returntype = this.returntype.checkTYPE(localAss, this); this.returntype = this.returntype.checkTYPE(localAss, this);
/*
* if(this.returntype!=null && (this.returntype instanceof RefType)&&
* !(this.returntype instanceof mycompiler.mytype.Void)){//Sonderfall
* der Methode: Ihr Typ darf Void definiert werden. Type replaceType =
* null; replaceType = ass.getTypeFor((RefType)this.returntype);
* if(replaceType == null)throw new
* TypeinferenceException("Der Typ "+this
* .getType().getName()+" ist nicht korrekt",this); this.returntype =
* replaceType; }
*/
// Die Parameter zu den Assumptions hinzufügen: // Die Parameter zu den Assumptions hinzufügen:
if (this.parameterlist != null) if (this.parameterlist != null)
for (FormalParameter param : this.parameterlist) { for (FormalParameter param : this.parameterlist) {
param.setType(param.getType().checkTYPE(localAss, this)); param.setType(param.getType().checkTYPE(localAss, this));
/*
* if(param.getType() instanceof RefType) { Type replaceType =
* null; replaceType = ass.getTypeFor((RefType)param.getType());
* if(replaceType == null) throw new
* TypeinferenceException("Der Typ "
* +param.getType().getName()+" ist nicht korrekt",param);
* param.setType(replaceType); }
*/
localAss.addAssumption(new ParameterAssumption(param)); localAss.addAssumption(new ParameterAssumption(param));
} }
ret.add(this.block.TYPEStmt(localAss)); ret.add(this.block.TYPEStmt(localAss));
@ -587,107 +537,15 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
TypeAssumptions ret = new TypeAssumptions(); TypeAssumptions ret = new TypeAssumptions();
ret.addAssumption(new MethodAssumption(this, parentClass)); ret.addAssumption(new MethodAssumption(this, parentClass));
return ret; return ret;
/*
* TypeAssumptions assumptions = new TypeAssumptions(); this.assumedType
* = null; //if((this.get_Method_Name().equals(classmember.getName()) ||
* this.get_Method_Name().equals("<init>")) &&
* ((this.getType().equals(new mycompiler.mytype.Void(0))) ||
* this.getType() instanceof TypePlaceholder)){
* if((this.get_Method_Name().equals(classmember.getName()) ||
* this.get_Method_Name().equals("<init>"))) {
* this.set_Method_Name("<init>"); this.assumedType = new
* RefType(classmember.getName(),0);
* this.setReturnType(this.assumedType); this.assumedType = new
* RefType("void",0); //Return constructorReturnStatement = new
* Return(0,0); //constructorReturnStatement.retexpr =
* //this.block.statements.add(constructorReturnStatement); } //hoth:
* 06.04.2006 //durchlaufe Block und suche nach Objektvariablen fuer
* Offset-Markierung Iterator<CTypeAssumption> fieldVarIterator =
* assumptions.iterator(); while (fieldVarIterator.hasNext()) { //Wenn
* ObjektVariable CTypeAssumption dieAssum = fieldVarIterator.next();
* if(dieAssum instanceof CInstVarTypeAssumption) {
* Class.isFirstLocalVarDecl=false; if(this.get_Block() != null)
* this.get_Block
* ().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true); }
* }
*
* //methodList.addElement(method);
*
* //¯Â¿Â½r V_fields_methods: CMethodTypeAssumption methodAssum
* = new CMethodTypeAssumption(classmember.getType(),
* this.get_Method_Name(), this.getType(),
* this.getParameterCount(),this.getLineNumber(),this.getOffset(),new
* Menge<Integer>(),this.getGenericMethodParameters()); // Typannahme
* bauen...
*
*
* //Methode in V_Fields_methods ablegen //Dabei wird die
* OverloadedMethodID ermittelt !! //=> Method setzenuct
*
*
* assumptions.add(methodAssum);
* this.setOverloadedID(methodAssum.getHashSetKey
* ().getOverloadedMethodID());
*
*
* //¯Â¿Â½r die V_i: CTypeAssumptionSet localAssum = new
* CTypeAssumptionSet();
*
* //Bauen... ParameterList parameterList = this.getParameterList();
* if(parameterList!=null){ for(int i=0;
* i<parameterList.sc_get_Formalparalist().size(); i++){ FormalParameter
* para = parameterList.sc_get_Formalparalist().elementAt(i); //
* ¯Â¿Â½r V_fields_methods: CParaTypeAssumption paraAssum = new
* CParaTypeAssumption(classmember.getName(), this.get_Method_Name(),
* this.getParameterCount(), this.getOverloadedID(),para.get_Name(),
* para.getType(), para.getLineNumber(),para.getOffset(),new
* Menge<Integer>()); //fuege Offsets fuer Parameter hinzu, hoth:
* 06.04.2006 Class.isFirstLocalVarDecl=false;
*
* if(this.get_Block() != null)
* this.get_Block().addOffsetsToAssumption(paraAssum
* ,paraAssum.getIdentifier(),true);
*
* methodAssum.addParaAssumption(paraAssum);
*
* // ¯Â¿Â½r die V_i: CLocalVarTypeAssumption varAssum = new
* CLocalVarTypeAssumption(classmember.getName(),
* this.get_Method_Name(), this.getParameterCount(),
* this.getOverloadedID(),"1", para.get_Name(),para.getType(),
* para.getLineNumber(),para.getOffset(),new Menge<Integer>());
* localAssum.addElement(varAssum);
* //rememberLocals.addElement(varAssum); } } //...und
* hinzuf�gen:
*
* assumptions.add(localAssum);//Assumptions ¼r lokale Variablen den
* Assumptions hinzufügen
*
* //Hier wird der Typ der als Assumption eingetragen wird in die
* Variable assumedType dieser Klasse geschrieben: if(this.assumedType
* == null) // Falls der Typ nicht schon gesetzt ist. Das ist der Fall,
* falls die Methode ein Konstruktor ist this.assumedType =
* methodAssum.getAssumedType();
*
* return assumptions;
*/
} }
@Override @Override
public void parserPostProcessing(SyntaxTreeNode parent) { public void parserPostProcessing(SyntaxTreeNode parent) {
if (this.getType() == null) if (this.getType() == null)
this.setType(TypePlaceholder.fresh(this)); this.setType(TypePlaceholder.fresh(this));
// Bei dem Elterntyp der Methode darf es sich nur um eine Klasse
// handeln, daher Cast ohne Prüfung:
// Class parentClass = (Class)parent;
if (this.returntype == null) if (this.returntype == null)
this.returntype = TypePlaceholder.fresh(this); this.returntype = TypePlaceholder.fresh(this);
super.parserPostProcessing(parent); super.parserPostProcessing(parent);
/*
* this.returntype.parserPostProcessing(this); if(this.parameterlist !=
* null){ for(FormalParameter fp : this.parameterlist){
* fp.parserPostProcessing(this); } } for(GenericTypeVar gtv :
* this.getGenericParameter()){ gtv.parserPostProcessing(this); }
*/
} }
@Override @Override
@ -728,7 +586,6 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
DImethod.set_Name(withSignature); DImethod.set_Name(withSignature);
ret.set_DeclId(DImethod); ret.set_DeclId(DImethod);
Block tempBlock = new Block(); Block tempBlock = new Block();
// tempBlock.setType(new RefType(parent.getName(),0));
ret.set_Block(tempBlock); ret.set_Block(tempBlock);
ret.parserPostProcessing(parent); ret.parserPostProcessing(parent);
return ret; return ret;
@ -751,7 +608,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
return super.equals(obj); return super.equals(obj);
} }
public void genByteCode(ClassGenerator cg) { public void genByteCode(ClassGenerator cg, Class classObj) {
List<TypeinferenceResultSet> typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg); List<TypeinferenceResultSet> typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg);
for(TypeinferenceResultSet t: typeInterferenceResults){ for(TypeinferenceResultSet t: typeInterferenceResults){
@ -771,10 +628,15 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
argumentNames[i] = parameter.getIdentifier(); argumentNames[i] = parameter.getIdentifier();
i++; i++;
} }
}
if(!createdMethods.contains(argumentTypes, new ArgumentTypeEquals())){
createdMethods.add(argumentTypes); String nameAndSignature = get_Method_Name()+Arrays.toString(argumentTypes);
}
Logger.getLogger("nameAndSignature").error(nameAndSignature, Section.CODEGEN);
if(classObj.methodExists(nameAndSignature)){
Logger.getLogger("methodExists").debug(this.toString(), Section.CODEGEN);
continue;
} }
short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public
@ -787,45 +649,10 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
//Methode generieren und anfügen: //Methode generieren und anfügen:
cg.addMethod(method.createMethod(cg, getParameterList(), returnType, get_Block(), t)); cg.addMethod(method.createMethod(cg, getParameterList(), returnType, get_Block(), t));
classObj.addMethod(nameAndSignature);
/* Logger.getLogger("createMethod").debug(this.toString(), Section.CODEGEN);
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 = 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()));
*/
} }
} }
} }
class ArgumentTypeEquals implements Equal<org.apache.commons.bcel6.generic.Type[]>{
@Override
public boolean equal(org.apache.commons.bcel6.generic.Type[] a, org.apache.commons.bcel6.generic.Type[] b) {
if(a.length != b.length){
Logger.getLogger("ArgumentTypeEquals").error("false(length)", Section.CODEGEN);
return false;
}
for(int i = 0; i < a.length; i++){
if(!a[i].equals(b[i])){
String as = a[i].toString();
String bs = b[i].toString();
Logger.getLogger("ArgumentTypeEquals").error("false "+as+" != "+bs, Section.CODEGEN);
return false;
}
}
Logger.getLogger("ArgumentTypeEquals").error("true", Section.CODEGEN);
return true;
}
}
// ino.end // ino.end

View File

@ -0,0 +1,8 @@
import java.util.Vector;
class AutoOverloadingMultiResults{
void method(Integer a) {
b;
b = 1;
}
}

View File

@ -0,0 +1,36 @@
package bytecode.types;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Vector;
import org.junit.Test;
import org.junit.Ignore;
import bytecode.SourceFileBytecodeTest;
public class AutoOverloadingMultiResultsTest extends SourceFileBytecodeTest{
@Override
protected void init() {
testName = "AutoOverloadingMultiResults";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
}
@Test
@Ignore
public void testConstruct() throws Exception{
ClassLoader classLoader = getClassLoader();
Class cls = classLoader.loadClass(testName);
Object obj = cls.newInstance();
assertTrue(true);
}
}

View File

@ -43,7 +43,7 @@ public class AutoOverloadingVectorTest extends SourceFileBytecodeTest{
URL url = file.toURL(); URL url = file.toURL();
URL[] urls = new URL[]{url}; URL[] urls = new URL[]{url};
Class string = classLoader.loadClass("java.lang.String"); Class string = classLoader.loadClass("java%util%Vector%%java%lang%String%");
Class[] params = new Class[1]; Class[] params = new Class[1];
params[0] = string; params[0] = string;
@ -69,13 +69,13 @@ public class AutoOverloadingVectorTest extends SourceFileBytecodeTest{
URL url = file.toURL(); URL url = file.toURL();
URL[] urls = new URL[]{url}; URL[] urls = new URL[]{url};
Integer integer = new Integer(123); Class integer = classLoader.loadClass("java%util%Vector%%java%lang%Integer%");
Class[] params = new Class[1]; Class[] params = new Class[1];
params[0] = integer.getClass(); params[0] = integer;
Method method = cls.getDeclaredMethod("method2", params); Method method = cls.getDeclaredMethod("method2", params);
method.invoke(obj, integer); method.invoke(obj, integer.newInstance());
assertTrue(true); assertTrue(true);
}catch(Exception e){ }catch(Exception e){
throw new RuntimeException(e); throw new RuntimeException(e);

View File

@ -1,6 +1,6 @@
import java.util.Vector; import java.util.Vector;
class SuperType{ class ExtendsType{
Vector<Integer> integerVector; Vector<Integer> integerVector;
void method() { void method() {

View File

@ -16,7 +16,7 @@ import bytecode.SourceFileBytecodeTest;
public class ExtendsTypeTest extends SourceFileBytecodeTest{ public class ExtendsTypeTest extends SourceFileBytecodeTest{
@Override @Override
protected void init() { protected void init() {
testName = "SuperType"; testName = "ExtendsType";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/"; rootDirectory = System.getProperty("user.dir")+"/test/bytecode/types/";
} }

View File

@ -4,6 +4,7 @@ import static org.junit.Assert.*;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Vector;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -60,13 +61,13 @@ public class ExtendsVectorStringTest extends ASTBytecodeTest{
Object obj = cls.newInstance(); Object obj = cls.newInstance();
Class stringClass = classLoader.loadClass("java.lang.Object"); Class objectClass = classLoader.loadClass("java.lang.Object");
Class[] params = new Class[1]; Class[] params = new Class[1];
params[0] = stringClass; params[0] = objectClass;
Method method = cls.getDeclaredMethod("add", params); Method method = cls.getDeclaredMethod("add", params);
method.invoke(obj, stringClass.newInstance()); method.invoke(obj, objectClass.newInstance());
}catch(Exception e){ }catch(Exception e){
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -83,5 +84,9 @@ public class ExtendsVectorStringTest extends ASTBytecodeTest{
public String getTestName() { public String getTestName() {
return "ExtendsVectorString"; return "ExtendsVectorString";
} }
class StringVector extends Vector<String>{
}
} }