Fehler in FieldDeclaration behoben. Signaturen an Methoden und Klassen angefügt

This commit is contained in:
JanUlrich 2015-09-17 20:57:33 +02:00
parent a9611fdd90
commit 296ffbe297
14 changed files with 92 additions and 13 deletions

View File

@ -0,0 +1,12 @@
package de.dhbwstuttgart.bytecode;
import org.apache.commons.bcel6.Constants;
import org.apache.commons.bcel6.generic.ReferenceType;
public class TypePlaceholderType extends ReferenceType{
public TypePlaceholderType(String name) {
super(Constants.T_REFERENCE, "T" + name + ";");
}
}

View File

@ -10,7 +10,7 @@ public class WildcardType extends ReferenceType{
public WildcardType(String class_name, String preString) {
super(Constants.T_REFERENCE, preString + "L" + class_name.replace('.', '/') + ";");
this.type = Constants.T_UNKNOWN;
//this.type = Constants.T_UNKNOWN;
}
}

View File

@ -111,6 +111,20 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
c.genByteCode(_cg, fieldInitializations);
}
String typeAttributeSignature = "";
if(this.getGenericParameter() != null && this.getGenericParameter().size()>0){
typeAttributeSignature = "<";
for(GenericTypeVar gp : this.getGenericParameter()){
typeAttributeSignature+=gp.getBytecodeSignature(_cg);
}
typeAttributeSignature+=">";
}
String superClassSignature = this.getSuperClass().getBytecodeSignature(_cg);
String classSignature = typeAttributeSignature + superClassSignature;
if(classSignature.length()>0){
_cg.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(classSignature),_cp.getConstantPool()));
}
ByteCodeResult code = new ByteCodeResult(_cg);
return code;
}

View File

@ -12,11 +12,13 @@ import org.apache.commons.bcel6.generic.MethodGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -30,6 +32,7 @@ import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
@ -70,10 +73,13 @@ public class Constructor extends Method {
Block block = this.get_Block();
if(block.statements.firstElement() instanceof SuperCall){
block.statements.insertElementAt(new BytecodeInstructionBlock(fieldInitializations), 1);
}else{
throw new DebugException("Fehlender SuperCall im Konstruktor");
}
InstructionList blockInstructions = block.genByteCode(cg);
il.append(blockInstructions);//Die vom Block generierten Instructions an die InstructionList der Methode anfügen
il.append(blockInstructions);
il.append(DHBWInstructionFactory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); //Konstruktor hat immer VOID Return type
this.method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden)

View File

@ -8,6 +8,7 @@ import java.util.Hashtable;
import java.util.Iterator;
import org.apache.commons.bcel6.Constants;
import org.apache.commons.bcel6.classfile.Signature;
import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.ConstantPoolGen;
import org.apache.commons.bcel6.generic.InstructionFactory;
@ -780,6 +781,16 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden)
method.setMaxLocals();
//Die korrekte Signatur für die Methode anhängen. Hier sind dann auch die Parameter von RefTypes enthalten:
String paramTypesSig = "(";
for(FormalParameter p : this.parameterlist){
paramTypesSig += p.getType().getBytecodeSignature(cg);
}
paramTypesSig += ")";
String retTypeSig = this.getType().getBytecodeSignature(cg);
method.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(paramTypesSig+retTypeSig),_cp.getConstantPool()));
cg.addMethod(method.getMethod());
}

View File

@ -99,7 +99,7 @@ public class SuperCall extends ThisCall
//Instructionhandle dynamisch
InstructionHandle ih_0 = il.append(_factory.createLoad( org.apache.commons.bcel6.generic.Type.OBJECT, 0));
il.append(_factory.createInvoke(superClass.getName().toString(), "<init>", org.apache.commons.bcel6.generic.Type.VOID, org.apache.commons.bcel6.generic.Type.NO_ARGS, Constants.INVOKESPECIAL));
InstructionHandle ih_4 = il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID));
//InstructionHandle ih_4 = il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID));
return il;
}

View File

@ -814,21 +814,26 @@ public class RefType extends ObjectType implements IMatchable
}
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName());
}
@Override
public String getBytecodeSignature(ClassGenerator cg) {
String paramString = "";
boolean printParameterList = false; //Die ParameterListe wird wohl nicht in allen Fällen gebraucht
if(printParameterList &&
this.parameter != null && this.parameter.size()>0){
if(this.parameter != null && this.parameter.size()>0){
paramString+="<";
Iterator<Type> it = this.parameter.iterator();
while(it.hasNext()){
Type param = it.next();
paramString+=param.getBytecodeType(cg);
paramString+=param.getBytecodeType(cg).getSignature();
//if(it.hasNext())
//paramString+=";"; //kein Delimiter zwischen den Typen
}
paramString+=">";
}
return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName()+paramString);
String typeSignature = this.getBytecodeType(cg).getSignature();
typeSignature = typeSignature.substring(0, typeSignature.length()-1);
return typeSignature+paramString+";";
}
}

View File

@ -306,6 +306,9 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset
}
public abstract org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg);
public String getBytecodeSignature(ClassGenerator cg) {
return this.getBytecodeType(cg).getSignature();
}
}
// ino.end

View File

@ -9,6 +9,7 @@ import java.util.Iterator;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.*;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.TypePlaceholderType;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
@ -431,9 +432,10 @@ public class TypePlaceholder extends ObjectType
@Override
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
//throw new TypeinferenceException("Zuerst alle Typen einsetzen vor dem Kompiliervorgang",this);
Type resolvedType = cg.resolveTPH(this);
if(resolvedType instanceof TypePlaceholder)throw new DebugException("Kann TypePlaceholder nicht auflösen");
if(resolvedType instanceof TypePlaceholder){
return new TypePlaceholderType(resolvedType.get_Name());
}
return resolvedType.getBytecodeType(cg);
}

3
test/bytecode/Fun1.java Normal file
View File

@ -0,0 +1,3 @@
interface Fun1<A,B>{
A apply(B p);
}

View File

@ -0,0 +1,3 @@
class GenericsTest<A, B extends A>{
Fun0<B> op;
}

View File

@ -0,0 +1,5 @@
class Identity{
op = (x)->x;
}

View File

@ -0,0 +1,14 @@
package bytecode;
import org.junit.Test;
public class IdentityTest {
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
public final static String testFile = "Identity.jav";
public final static String outputFile = "Identity.class";
@Test
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}
}

View File

@ -3,11 +3,12 @@
*/
class Test{
public static void main(String[] args){
/*new EmptyClass();
new EmptyClass();
new Assign();
System.out.println(new Return().method());
new MethodCall().method();
System.out.println(new FieldDeclaration().field);*/
System.out.println(new FieldDeclaration().field);
System.out.println(new Runnable().method().apply());
Runnable r = new Runnable().method().apply();
}
}