From 64bed0c60dcaf4018af203510204220a07f01336 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 27 Aug 2015 16:36:19 +0200 Subject: [PATCH] MethodCall implementiert --- .classpath | 2 +- src/de/dhbwstuttgart/syntaxtree/Class.java | 4 ++ src/de/dhbwstuttgart/syntaxtree/Field.java | 2 +- .../dhbwstuttgart/syntaxtree/Interface.java | 5 ++- .../dhbwstuttgart/syntaxtree/SourceFile.java | 1 + .../syntaxtree/statement/Assign.java | 8 ++-- .../syntaxtree/statement/Binary.java | 2 +- .../syntaxtree/statement/Expr.java | 2 +- .../syntaxtree/statement/MethodCall.java | 37 ++++++++++++++++++- .../syntaxtree/statement/Receiver.java | 8 ++++ .../syntaxtree/statement/This.java | 3 +- .../syntaxtree/type/RefType.java | 3 +- .../assumptions/TypeAssumptions.java | 7 ++++ test/bytecode/MethodCall.jav | 4 +- test/bytecode/Test.java | 1 + 15 files changed, 73 insertions(+), 16 deletions(-) diff --git a/.classpath b/.classpath index b02a00af..3c2e81f4 100755 --- a/.classpath +++ b/.classpath @@ -8,6 +8,6 @@ - + diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index bc16e212..e694a1a5 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -1353,5 +1353,9 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I public boolean isClass() { return true; } + + public boolean isInterface(){ + return false; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 55c553ac..77011a5f 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -174,7 +174,7 @@ public abstract class Field extends GTVDeclarationContext implements TypeInserta } /** - * Fügt das das Feld zu ClassGen hinzu + * F�gt das das Feld zu ClassGen hinzu * @param cg */ public abstract void genByteCode(ClassGen cg); diff --git a/src/de/dhbwstuttgart/syntaxtree/Interface.java b/src/de/dhbwstuttgart/syntaxtree/Interface.java index eb5aff6a..d7a4754b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Interface.java +++ b/src/de/dhbwstuttgart/syntaxtree/Interface.java @@ -4,7 +4,6 @@ package de.dhbwstuttgart.syntaxtree; // ino.module.Interface.8582.import import de.dhbwstuttgart.typeinference.Menge; - import de.dhbwstuttgart.core.AClassOrInterface; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.misc.UsedId; @@ -44,6 +43,10 @@ public class Interface extends Class { } + @Override + public boolean isInterface(){ + return true; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 43ddecc0..0adcb710 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -129,6 +129,7 @@ public class SourceFile public Menge InterfaceVektor = new Menge(); // ino.end + /** * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. * SourceFile stellt dabei den Wurzelknoten des Syntaxbaumes dar. diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java index 2b38bc8b..5aa376b8 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java @@ -175,14 +175,14 @@ public class Assign extends Expr } - public static int counterAssign = 0; //Zaehlvariable für ISTORE + public static int counterAssign = 0; //Zaehlvariable f�r ISTORE @Override - public InstructionList genByteCode(ClassGen cg) { + public InstructionList genByteCode(ClassGen cg, TypeAssumptions ass) { // TODO Auto-generated method stub InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool()); - InstructionList il = expr2.genByteCode(cg);//expr2 rechte expr - counterAssign++; //macht STORE für meherere Variable nutzbar (nicht nur ISTORE_1, ISTORE_2, etc.) + InstructionList il = expr2.genByteCode(cg, ass);//expr2 rechte expr + counterAssign++; //macht STORE f�r meherere Variable nutzbar (nicht nur ISTORE_1, ISTORE_2, etc.) String expr2Type = expr2.getType().get_Name().toString(); diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java index 21b01773..2f0b3b7d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java @@ -217,7 +217,7 @@ public JavaCodeResult printJavaCode(ResultSet resultSet) { @Override - public InstructionList genByteCode(ClassGen _cg) { + public InstructionList genByteCode(ClassGen _cg, TypeAssumptions ass) { InstructionList linkeSeite = this.expr1.genByteCode(_cg); InstructionList rechteSeite = this.expr2.genByteCode(_cg); if(this.getReturnType().getName().equals(new JavaClassName("String"))){ diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Expr.java b/src/de/dhbwstuttgart/syntaxtree/statement/Expr.java index f625c9ed..6feade6f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Expr.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Expr.java @@ -113,6 +113,6 @@ public abstract class Expr extends ExprStmt throw new NotImplementedException(); //wird die TYPEStmt-Methode innerhalb einer Expr aufgerufen, dann ist etwas schief gelaufen. } - public abstract InstructionList genByteCode(ClassGen _cg); + //public abstract InstructionList genByteCode(ClassGen _cg, TypeAssumptions ass); } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 3fffb2cf..370107c8 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -4,7 +4,10 @@ package de.dhbwstuttgart.syntaxtree.statement; // ino.module.MethodCall.8639.import import java.util.Hashtable; +import org.apache.bcel.Constants; import org.apache.bcel.generic.ClassGen; +import org.apache.bcel.generic.InstructionFactory; +import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionList; import de.dhbwstuttgart.typeinference.Menge; @@ -206,6 +209,9 @@ public class MethodCall extends Expr //Noch das Overloading-Constraint anhängen: ret.add(overloading(assumptions)); + de.dhbwstuttgart.syntaxtree.Class receiverCl = assumptions.getClassAssumptionFor(receiver.get_Expr().getType()).getAssumedClass(); + this.receiver.setClass(receiverCl); + return ret; } @@ -308,9 +314,36 @@ public class MethodCall extends Expr @Override public InstructionList genByteCode(ClassGen _cg) { - //Herausfinden, ob eine Methode oder ein Interface aufgerufen wird: - //this.receiver.get_Expr().getType() + InstructionList il = new InstructionList(); + InstructionFactory _factory = new InstructionFactory(_cg, _cg.getConstantPool()); + il.append(receiver.get_Expr().genByteCode(_cg)); + + //Herausfinden, ob eine Methode oder ein Interface aufgerufen wird: + Type receiverType = this.receiver.get_Expr().getType(); + de.dhbwstuttgart.syntaxtree.Class receiverClass = this.receiver.getReceiverClass(); + short kind = 0; + if(receiverClass.isInterface()){ + kind = Constants.INVOKEINTERFACE; + }else{//Ansonsten muss es eine Klasse sein: + kind = Constants.INVOKEVIRTUAL; + } + + org.apache.bcel.generic.Type[] argumentTypen = org.apache.bcel.generic.Type.NO_ARGS; + if(this.getArgumentList() != null && this.getArgumentList().size()>0){ + argumentTypen = new org.apache.bcel.generic.Type[this.getArgumentList().size()]; + int i = 0; + for(Expr argument : this.arglist.expr){ + argumentTypen[i] = argument.getType().getBytecodeType(); + //Das Argument auf den Stack legen: + il.append(argument.genByteCode(_cg)); + i++; + } + } + + org.apache.bcel.generic.Type returnType = this.getType().getBytecodeType(); + il.append(_factory.createInvoke(receiver.getReceiverClass().getName().toString(), this.get_Name(), returnType , argumentTypen, kind)); + return il; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java index 15a130a6..304639a6 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java @@ -27,6 +27,7 @@ public class Receiver { // ino.attribute.expr.26126.declaration private Expr expr; + private de.dhbwstuttgart.syntaxtree.Class receiverClass; // ino.end // ino.attribute.parserlog.26129.declaration protected static Logger parserlog = Logger.getLogger("parser"); @@ -89,6 +90,13 @@ public class Receiver } // ino.end + public void setClass(Class cl){ + this.receiverClass = cl; + } + + public Class getReceiverClass(){ + return this.receiverClass; + } public JavaCodeResult printJavaCode(ResultSet resultSet) { return new JavaCodeResult().attach(this.get_Expr().printJavaCode(resultSet)); diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/This.java b/src/de/dhbwstuttgart/syntaxtree/statement/This.java index 1f5ed185..09ea299a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/This.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/This.java @@ -151,8 +151,7 @@ public class This extends Expr public InstructionList genByteCode(ClassGen _cg) { InstructionList il = new InstructionList(); InstructionHandle ih_0 = il.append(InstructionFactory.createLoad(org.apache.bcel.generic.Type.OBJECT, 0)); - InstructionHandle ih_1 = il.append(InstructionFactory.createReturn(org.apache.bcel.generic.Type.OBJECT)); - return il; + return il; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index c0875303..29637635 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -6,12 +6,13 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.myexception.SCException; import de.dhbwstuttgart.parser.JavaClassName; +import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.misc.UsedId; import de.dhbwstuttgart.typeinference.JavaCodeResult; diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java index 5b342445..96a6cd8b 100755 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java @@ -407,6 +407,13 @@ public class TypeAssumptions { public Menge getClassAssumptions() { return this.classAssumptions; } + + public ClassAssumption getClassAssumptionFor(Type t){ + for(ClassAssumption cA : this.getClassAssumptions()){ + if(cA.getAssumedClass().getType().equals(t))return cA; + } + throw new TypeinferenceException("Der Typ "+t+" ist nicht in den Assumptions vorhanden", t); + } public Type checkType(RefType type, SyntaxTreeNode parent) { Type t = this.getTypeFor(type, parent); //Richtigkeit des Typnahmensprüfen diff --git a/test/bytecode/MethodCall.jav b/test/bytecode/MethodCall.jav index cdedd45a..1ae031d5 100644 --- a/test/bytecode/MethodCall.jav +++ b/test/bytecode/MethodCall.jav @@ -1,7 +1,7 @@ -class Assign{ +class MethodCall{ void method() { -method(); +method2(); } void method2(){} diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java index 51e03e30..2c625925 100644 --- a/test/bytecode/Test.java +++ b/test/bytecode/Test.java @@ -6,5 +6,6 @@ public static void main(String[] args){ new EmptyClass(); new Assign(); System.out.println(new Return().method()); + new MethodCall().method(); } }