Revert "Syntaxbaum bereinigen. Allen Code löschen. Nur Struktur bleibt erhalten"

This reverts commit 3ab96a3ed7.
This commit is contained in:
JanUlrich 2016-12-16 01:05:54 +01:00
parent c329ba6cef
commit 7b9a00a7e6
572 changed files with 26882 additions and 150 deletions

View File

@ -0,0 +1,3 @@
jvmDisassebler.class
*~*
*.class

View File

@ -0,0 +1,18 @@
package de.dhbwstuttgart.JvmDisassembler;
class GenericsTest<a,b> {
Integer k;
GenericsTest<Integer,Integer> pp;
Object j;
a meth(a arg) {
return arg;
}
<t extends Integer> t meth2(b arg, t arg2) {
return arg2;
}
}

View File

@ -0,0 +1,231 @@
package de.dhbwstuttgart.JvmDisassembler;
import java.util.*;
import java.io.*;
import de.dhbwstuttgart.typeinference.Menge;
//GenricsTest.java Testfile fuer jvmDisassembler
class jvmDisassembler {
static int makePosByte(int code) {
return (code & 0x7f | code & 0x80);
}
static int makePosShort(int code) {
return (code & 0x7fff | code & 0x8000);
}
static long makePosInt(long code) {
return (code & 0x7fffffff | code & 0x80000000);
}
static void parse_attribute(DataInputStream d, Menge<String> const_pool) throws IOException, Exception {
int attribut_count = d.readShort();
System.out.println("attribut_count = " + attribut_count);
if (attribut_count == 0) System.out.println("attributes = {}");
else {
for (int j = 0; j < attribut_count; j++) {
System.out.println("attribut[" + j + "] =\n{");
int attribut_name_index = d.readShort();
System.out.println("attribut_name_index = " + attribut_name_index
+ " //" + const_pool.elementAt(makePosShort(attribut_name_index)));
if (const_pool.elementAt(makePosShort(attribut_name_index)).equals("Code")) {
parse_code(d, const_pool);
int exception_table_length = d.readShort();
System.out.println("exception_table_length = " + exception_table_length);
if (exception_table_length == 0) System.out.println("exception_table = {}");
else throw new Exception("exceptiones not implemented");
parse_attribute(d, const_pool);
} else {
if ((const_pool.elementAt(makePosShort(attribut_name_index)).equals("Signature"))) {
long attribut_length = d.readInt();
System.out.println("attribut_length = " + attribut_length);
int sigdescriptor_index = d.readShort();
System.out.println("descriptor_index = " + sigdescriptor_index
+ " //" + const_pool.elementAt(makePosShort(sigdescriptor_index)));
} else {
long attribut_length = d.readInt();
System.out.println("attribut_length = " + attribut_length);
for(int ll = 0; ll < attribut_length; ll++) {
System.out.println(Integer.toHexString(makePosByte(d.readByte())));
}
System.out.println("}");
}
}
System.out.println("}");
}
}
}
static void parse_code(DataInputStream d, Menge<String> const_pool) throws IOException {
long attribut_length = d.readInt();
System.out.println("attribut_length = " + attribut_length);
int max_stack = d.readShort();
System.out.println("max_stack = " + max_stack);
int max_locals = d.readShort();
System.out.println("max_locals = " + max_locals);
long code_length = makePosInt(d.readInt());
System.out.println("code_length = " + code_length);
System.out.println("code =\n{");
int code;
int codenr = 1;
for(; codenr <= code_length;) {
//CODE VERVOLLSTAENDIGEN PL 06-04-01
code = makePosByte(d.readByte());
//System.out.println("DEBUG: " + Integer.toHexString(code));
switch(code) {
case 0x4: System.out.println(" " + codenr + " iconst_1");
codenr++;
break;
case 0x2a: System.out.println(" " + codenr + " aload_0");
codenr++;
break;
case 0x2b: System.out.println(" " + codenr + " aload_1");
codenr++;
break;
case 0x2c: System.out.println(" " + codenr + " aload_2");
codenr++;
break;
case 0xac: System.out.println(" " + codenr + " ireturn");
codenr++;
break;
case 0xb0: System.out.println(" " + codenr + " areturn");
codenr++;
break;
case 0xb1: System.out.println(" " + codenr + " return");
codenr++;
break;
case 0xb7: System.out.println(" " + codenr + " invokespecial " +
d.readShort());
codenr+=3;
break;
default: System.out.println(" " + Integer.toHexString(code));
codenr++;
break;
}
}
System.out.println("}");
}
public static void main (String[] args) throws FileNotFoundException, IOException, Exception {
DataInputStream d = new DataInputStream(new FileInputStream(new File (args[0])));
int magic = d.readInt();
System.out.println("magic = 0x " + Integer.toHexString(magic));
int minor = d.readShort();
System.out.println("minor_version = " + minor);
int major = d.readShort();
System.out.println("major_version = " + major);
//CONSTANT POOL START
int constant_pool_count = makePosShort(d.readShort());
System.out.println("constant_pool_count = " + constant_pool_count);
Menge<String> const_pool = new Menge<String>();
const_pool.addElement(""); // Konstatenpool beginnt bei 1, Stelle 0 auffuellen
System.out.println("constant_pool =\n{");
short constant_pool_tag;
for (int i = 1; i < constant_pool_count; i++) {
constant_pool_tag = d.readByte();
switch(constant_pool_tag) {
//Tags vervollstaendigen PL 06-04-01
case 1: System.out.print(i + "| tag = CONSTANT_Utf8, length = ");
int length = makePosShort(d.readShort());
System.out.print(length + ", ");
byte[] bytes = new byte[length];
d.read(bytes, 0, length);
System.out.println(new String(bytes));
const_pool.addElement(new String(bytes));
break;
case 7: System.out.println(i + "| tag = CONSTANT_Class, name_index = " + d.readShort());
const_pool.addElement("");
break;
case 10: System.out.println(i + "| tag = CONSTANT_Methodref, class_index = " +
d.readShort() + ", name_and_type_index = " + d.readShort());
const_pool.addElement("");
break;
case 12:System.out.println(i + "| tag = CONSTANT_NameAndType, name_index = " +
d.readShort() + ", descriptor_index = " + d.readShort());
const_pool.addElement("");
break;
}
}
//CONSTANT POOL END
int access_flags = d.readShort();
System.out.println("access_flags = " + access_flags);
int this_class = d.readShort();
System.out.println("this_class = " + this_class);
int super_class = d.readShort();
System.out.println("super_class = " + super_class);
//INTERFACE START
int interface_count = d.readShort();
System.out.println("interface_count = " + interface_count);
if (interface_count == 0) System.out.println("interfaces ={}");
else
//Interface implementieren PL 06-04-01
throw new Exception("no interfaces implemented");
//INTERFACE END
//FIELD START
int field_count = d.readShort();
System.out.println("field_count = " + field_count);
if (field_count == 0) System.out.println("fields = {}");
else {
for(int o = 1; o <= field_count; o++) {
System.out.println("field[" + o + "] =\n{");
int faccess_flags = d.readShort();
System.out.println("access_flags = " + faccess_flags);
int fname_index = d.readShort();
System.out.println("name_index = " + fname_index);
int fdescriptor_index = d.readShort();
System.out.println("descriptor_index = " + fdescriptor_index);
parse_attribute(d, const_pool);
System.out.println("}");
}
}
//FIELD END
//METHOD START
int method_count = makePosShort(d.readShort());
System.out.println("method_count = " + method_count);
if (method_count == 0) System.out.println("methods ={}");
else {
for(int i = 1; i <= method_count; i++) {
System.out.println("method[" + i + "] =\n{");
int maccess_flags = d.readShort();
System.out.println("access_flags = " + maccess_flags);
int mname_index = d.readShort();
System.out.println("name_index = " + mname_index);
int descriptor_index = d.readShort();
System.out.println("descriptor_index = " + descriptor_index);
parse_attribute(d, const_pool);
System.out.println("}");
}
}
//METHOD END
//FILE ATTRIBUTES START
parse_attribute(d, const_pool);
//FILE ATTRIBUTES END
}
}

View File

@ -0,0 +1,89 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
public class BytecodeTypeFactory {
/**
* @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-FieldType
*/
public static String generateFieldDescriptor(RefType t){
String ret = "";
if(t instanceof RefType){
ret += "L" + t.getName().toString().replace('.', '/') + ";";
}else{
throw new NotImplementedException();
}
return ret;
}
/**
* @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ClassSignature
*/
public static String generateClassSignature(de.dhbwstuttgart.syntaxtree.Class c){
String ret = "";
if(c.getGenericParameter() != null && c.getGenericParameter().size() > 0){
ret += "<";
for(GenericTypeVar gtv : c.getGenericParameter()){
ret += generateTypeParameter(gtv);
}
ret += ">";
}
//Add the SuperClassSignature:
c.getSuperClass();
ret += generateClassTypeSignature();
return ret;
}
public static String generateSuperClassSignature(RefType superClass){
String ret = "";
//TODO:
throw new NotImplementedException();
}
private static String generateTypeParameter(GenericTypeVar gtv){
String ret = gtv.getName() + ":";
for(RefType t : gtv.getBounds()){
ret += generateReferenceTypeSignature(t);
ret += ":";
}
ret = ret.substring(0, ret.length()-1);
return ret;
}
/**
* @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ClassTypeSignature
*/
private static String generateClassTypeSignature(){
return null;
}
/**
* @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ReferenceTypeSignature
*/
private static String generateReferenceTypeSignature(RefType t){
if(t instanceof RefType)return generateReferenceTypeSignature((RefType)t);
throw new NotImplementedException();
}
private static String generateReferenceTypeSignature(RefType t){
String ret = "L" + t.getName();
if(t.getParaList() != null && t.getParaList().size() > 0){
ret += "<";
for(RefType p : t.getParaList()){
ret += generateReferenceTypeSignature(p);
}
ret+=">";
}
return ret + ";";
}
private static String generateReferenceTypeSignature(GenericTypeVar t){
String ret = "T" + t.get_Name();
return ret + ";";
}
}

View File

@ -0,0 +1,253 @@
package de.dhbwstuttgart.bytecode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.bcel.classfile.BootstrapMethod;
import org.apache.bcel.classfile.BootstrapMethods;
import org.apache.bcel.classfile.InnerClass;
import org.apache.bcel.classfile.InnerClasses;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Signature;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
public class ClassGenerator extends ClassGen{
private DHBWConstantPoolGen cp;
private DHBWInstructionFactory factory;
private TypeinferenceResults tiResult;
private int lambdaMethodeNr = 0;
private Type superClass;
private List<GenericTypeVar> generics;
private Menge<TypePlaceholder> usedTPHs = new Menge<>();
private Map<String, ClassGenerator> extraClasses = new HashMap<>();
private List<String> methodsNamesAndTypes = new LinkedList<>();
private MethodGenerator methodGenerator;
public ClassGenerator(JavaClassName name, Type superClass, List<GenericTypeVar> generics,
String sourceFileName, short accessflags, String[] implementedInterfaces, TypeinferenceResults rs) {
super(name.toString(),superClass.get_Name(),sourceFileName,accessflags,implementedInterfaces, new DHBWConstantPoolGen());
//this.tiResult = typeinferenceResultSet;
this.superClass = superClass;
this.generics = generics;
tiResult = rs;
cp = (DHBWConstantPoolGen) super.getConstantPool();
factory = new DHBWInstructionFactory(this, cp);
this.setMajor(52); //Java 8 Version 52.0
this.setMinor(0);
}
public DHBWInstructionFactory getInstructionFactory() {
return factory;
}
/**
* Versucht einen Type zu finden von dem dieser TPH ein Subtyp sein muss.
* @param toTPH
* @return Es gilt dann "toTPH extends Type"
public org.apache.bcel.generic.Type getNearestUsedType(Type t, Menge<TypePlaceholder> usedTypes){
if(t == null){
return this.getInstructionFactory().createObjectType();
}else if(t instanceof TypePlaceholder){ //Es muss sich in diesem Fall um einen TPH handeln:
//return getNearestType((TypePlaceholder) t);
return new TypePlaceholderType((TypePlaceholder) t);
}else{
return t.getBytecodeType(this, getTypeinferenceResultSet().getTypeReconstructions().get(0));
}
}
public org.apache.bcel.generic.Type getNearestUsedType(TypePlaceholder toTPH){
return this.getNearestUsedType(toTPH, null);
}
*/
public String createLambdaMethodName() {
return "lambda$methode$"+(lambdaMethodeNr++);
}
@Override
public DHBWConstantPoolGen getConstantPool(){
return this.cp;
}
@Override
public void setConstantPool(ConstantPoolGen gen){
throw new DebugException("Ungültige Operation. ClassGenerator muss ein DHBWConstantPool besitzen");
}
private List<InnerClass> innerClasses = new ArrayList<>();
/**
* Anmerkung: Kann in diesem Zustand nur einmal aufgerufen werden.
* @param innerClassAttribute
*/
public void addInnerClass(InnerClass innerClassAttribute) {
for(InnerClass innerClass : innerClasses){
//Equal-Check:
if(innerClassCompare(innerClassAttribute, innerClass)){
return; //Ist die Innere Klasse bereits vorhanden, ist ein weiteres Anfügen nicht notwendig
}
}
innerClasses.add(innerClassAttribute);
}
/**
* Prüft die InnerClass Attribute a und b auf Gleichheit.
* Hierbei wird davon ausgegangen, dass beide den gleichen ConstantPool benutzen und dieser keine redundanten Einträge enthält
* @param a
* @param b
* @return
*/
private boolean innerClassCompare(InnerClass a, InnerClass b){
if(a.getInnerAccessFlags() != b.getInnerAccessFlags()){
return false;
}else if(a.getInnerClassIndex() != b.getInnerClassIndex()){
return false;
}else if(a.getInnerNameIndex() != b.getInnerNameIndex()){
return false;
}else if(a.getOuterClassIndex() != b.getOuterClassIndex()){
return false;
}
return true;
}
private List<BootstrapMethod> bootstrapMethods= new ArrayList<>();
public int addBootstrapMethod(BootstrapMethod bMethod) {
bootstrapMethods.add(bMethod);
return bootstrapMethods.size()-1;
}
public void addUsedTPH(TypePlaceholder tph){
if(! this.getUsedTPH().contains(tph, (a, b)->{
return a.get_Name().equals(b.get_Name()); //Vergleich auf Namensgleichheit. Was anderes zählt im Bytecode nicht
}))
{ //Nur wenn noch nicht vorhanden anfügen:
this.usedTPHs.add(tph);
}
}
public Menge<TypePlaceholder> getUsedTPH() {
return usedTPHs;
}
@Override
public JavaClass getJavaClass() {
//Hier werden die letzten Schritte vor der Klassengenerierung ausgeführt:
//Signatur setzen:
String typeParameters = this.generateParameterSignature();
String superClassSignature = BytecodeTypeFactory.generateSuperClassSignature(this.superClass);//"L" + this.superClass.getBytecodeType(cg, rs)
superClassSignature = superClassSignature.substring(0, superClassSignature.length()-1); //Das ";" am Ende entfernen
if(this.superClass instanceof RefType &&
((RefType)superClass).get_ParaList() != null &&
((RefType)superClass).get_ParaList().size() > 0){
superClassSignature += "<";
RefType superRefType = (RefType) this.superClass;
for(Type param : superRefType.get_ParaList()){
superClassSignature += param.getBytecodeSignature(this, null);
}
superClassSignature += ">;";
}
String classSignature = typeParameters + superClassSignature; //TOOD: Hier noch die Signaturen der SuperInterfaces anfügen
if(classSignature.length()>0){
this.addAttribute(new Signature(cp.addUtf8("Signature"),2,cp.addUtf8(classSignature),cp.getConstantPool()));
}
//InnerClass Attribut hinzufügen:
int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClasses");
this.addAttribute(new InnerClasses(innerClassesUTF8,innerClasses.size()*8+2,
innerClasses.toArray(new InnerClass[innerClasses.size()]),this.getConstantPool().getConstantPool()));
//Bootstrap Methoden generieren:
int name_index = this.getConstantPool().addUtf8("BootstrapMethods");
int length = 2 + bootstrapMethods.size() * 4;// + bMethod.getNumBootstrapArguments() * 2;
for(BootstrapMethod bMethod : bootstrapMethods){
length += 2 * bMethod.getNumBootstrapArguments();
}
BootstrapMethod[] bootstrap_methods = bootstrapMethods.toArray(new BootstrapMethod[bootstrapMethods.size()]);
BootstrapMethods bootstrapAttribute = new BootstrapMethods(name_index, length, bootstrap_methods, this.getConstantPool().getConstantPool());
this.addAttribute(bootstrapAttribute);
return super.getJavaClass();
}
private String generateParameterSignature(){
String ret = "";
//ret += "L" + this.getClassName().replace(".", "/") + ";";
if(this.generics != null && this.generics.size() > 0){
ret += "<";
for(GenericTypeVar gtv : this.generics){
ret += gtv.getBytecodeSignature(this, tiResult.getTypeReconstructions().get(0));
}
ret += ">";
}
/*
if(this.getUsedTPH().size()>0){
ret += "<";
Iterator<TypePlaceholder> it = ((Menge<TypePlaceholder>)this.getUsedTPH().clone()).iterator();
while(it.hasNext()){
TypePlaceholder tph = it.next();
//ret += tph.getBytecodeMethodSignature(this);
//ret += ":";
ret += tph.getClassSignature(this, null); //Es wird null übergeben. Die ClassSignaturen dürfen von keinem ResultSet abhängen.
}
ret += ">";
}
*/
return ret;
}
public void addExtraClass(ClassGenerator cg){
extraClasses.put(cg.getClassName(), cg);
}
public Map<String, ClassGenerator> getExtraClasses() {
return extraClasses;
}
/*
public TypeinferenceResults getTypeinferenceResultSet() {
return tiResult;
}
*/
@Override
public void addMethod(Method m) {
//TODO: Die Prüfung, ob Methode bereits vorhanden vor die Bytecodegenerierung verlegen (Beispielsweise in Method)
String methodNameAndTypes = m.getReturnType().toString()+";"+m.getName()+"("+Arrays.toString(m.getArgumentTypes());
if(methodsNamesAndTypes.contains(methodNameAndTypes)){
return;
}
methodsNamesAndTypes.add(methodNameAndTypes);
super.addMethod(m);
}
public void setMethodeGenerator(MethodGenerator methodGenerator) {
this.methodGenerator = methodGenerator;
}
public MethodGenerator getMethodGenerator() {
return methodGenerator;
}
}

View File

@ -0,0 +1,36 @@
package de.dhbwstuttgart.bytecode;
import java.util.HashMap;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.ConstantMethodHandle;
import org.apache.bcel.classfile.ConstantMethodType;
import org.apache.bcel.generic.ConstantPoolGen;
public class DHBWConstantPoolGen extends ConstantPoolGen{
private static final long serialVersionUID = -8282768548793548585L;
private final HashMap<Constant, Integer> constantTable = new HashMap<>();
//private static final String DELIMITER = "$";
/*
public int addConstantMethodType(ConstantMethodType methodType) {
if(constantTable.containsKey(methodType))return constantTable.get(methodType);
}
public int addConstantMethodHandle(ConstantMethodHandle methodHandle) {
if(constantTable.containsKey(methodHandle))return constantTable.get(methodHandle);
int ret = this.index;
return ret;
}
*/
public int addConstant(Constant c){
if(constantTable.containsKey(c))return constantTable.get(c);
int ret = this.index;
this.constants[this.index++] = c;
constantTable.put(c, ret);
return ret;
}
}

View File

@ -0,0 +1,70 @@
package de.dhbwstuttgart.bytecode;
import java.awt.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Attribute;
import org.apache.bcel.classfile.BootstrapMethod;
import org.apache.bcel.classfile.ConstantInvokeDynamic;
import org.apache.bcel.classfile.ConstantMethodHandle;
import org.apache.bcel.classfile.ConstantMethodType;
import org.apache.bcel.classfile.InnerClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Signature;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.INVOKEDYNAMIC;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LocalVariableInstruction;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.Type;
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.FunN;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
public class DHBWInstructionFactory extends InstructionFactory{
private DHBWConstantPoolGen cp;
private ClassGenerator cg;
private static Map<String, Integer> storeIndexes = new HashMap<>();
public DHBWInstructionFactory(ClassGenerator cg, DHBWConstantPoolGen cp) {
super(cg, cp);
this.cp = cp;
this.cg = cg;
}
/**
*
* @param interfaceMethodName - Momentan immer "apply"
* @param invokeDynamicMethodType - Der Typ der Methode, welche Dynamisch aufgerufen werden soll
* @return
*/
public INVOKEDYNAMIC createInvokeDynamic( String interfaceMethodName, String invokeDynamicMethodType, BootstrapMethod bMethod) {
int bootstrap_method_attr_index = cg.addBootstrapMethod(bMethod);
int invokeDynamicFunktionstyp = cp.addNameAndType(interfaceMethodName, invokeDynamicMethodType);
ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, invokeDynamicFunktionstyp);
int index = cp.addConstant(cInvokeDynamic);
return new INVOKEDYNAMIC(index);
}
public static Type createObjectType() {
return new org.apache.bcel.generic.ObjectType("java.lang.Object");
}
public Attribute createSignatureAttribute(String signature) {
return new Signature(cp.addUtf8("Signature"),2,cp.addUtf8(signature),cp.getConstantPool());
}
}

View File

@ -0,0 +1,132 @@
package de.dhbwstuttgart.bytecode;
import java.awt.List;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import org.apache.bcel.classfile.Attribute;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.ConstantUtf8;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Signature;
import org.apache.bcel.classfile.StackMap;
import org.apache.bcel.classfile.StackMapEntry;
import org.apache.bcel.classfile.Visitor;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.Instruction;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LocalVariableInstruction;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.StackMapTableGen;
import org.apache.bcel.generic.Type;
import org.apache.bcel.Const;
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.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
public class MethodGenerator extends MethodGen{
private Map<String, Integer> storeIndexes = new HashMap<>();
public MethodGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name,
String class_name, InstructionList il, ConstantPoolGen cp) {
super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp);
for(String name: arg_names){
getStoreIndex(name);
}
}
public Method createMethod(ClassGenerator cg, ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type retType,
Block block, TypeinferenceResultSet rs){
MethodGen method = this;
DHBWInstructionFactory factory = cg.getInstructionFactory();
InstructionList blockInstructions = block.genByteCode(cg, rs);
InstructionList il = this.getInstructionList();
il.append(blockInstructions);//Die vom Block generierten Instructions an die InstructionList der Methode anfügen
//Ein return Statement anfügen, falls nicht vorhanden:
//TODO: Das ist schlecht! Der Parser oder der Typinferenzalgorithmus muss dafür sorgen, dass sich in jeder Methode ein Return befindet.
if (block.get_Statement().size() == 0) { il.append(factory.createReturn( org.apache.bcel.generic.Type.VOID)); }
else {
java.util.List<Statement> stmts = block.get_Statement();
if (!(stmts.get(stmts.size()-1) instanceof Return) &&
this.getType().equals(org.apache.bcel.generic.Type.VOID)) {
il.append(factory.createReturn( org.apache.bcel.generic.Type.VOID));
}
}
method.getInstructionList().setPositions();
method.stripAttributes(true);
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 methodDescriptor = getMethodDescriptor(parameter, retType, cg, rs);
method.addAttribute(factory.createSignatureAttribute(methodDescriptor));
System.out.println(this.getInstructionList().size());
StackMap stackMap = new StackMapTableGen(this, cp).getStackMap();
if(stackMap != null)method.addCodeAttribute(stackMap);
return method.getMethod();
}
/**
* Erstellt den Deskriptor für eine Method mit den angegebenen Parametern und Return Typ.
* Dies ist eine optionale Angabe im java Bytecode und enthält im Gegensatz zur Signatur der Methode auch Generics.
* @param parameter
* @param returnType
* @param cg
* @param rs
* @return
*/
public static String getMethodDescriptor(ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type returnType, ClassGenerator cg, TypeinferenceResultSet rs){
String paramTypesSig = "(";
for(FormalParameter p : parameter){
paramTypesSig += p.getType().getBytecodeSignature(cg, rs);
//Logger.getLogger("MethodGenerator").error(paramTypesSig, Section.CODEGEN);
}
paramTypesSig += ")";
String retTypeSig = returnType.getBytecodeSignature(cg, rs);
return paramTypesSig+retTypeSig;
}
public LocalVariableInstruction createLoad(org.apache.bcel.generic.Type bytecodeType, String variableName) {
return InstructionFactory.createLoad(bytecodeType, getStoreIndex(variableName));
}
public LocalVariableInstruction createStore(org.apache.bcel.generic.Type bytecodeType, String variableName) {
return InstructionFactory.createStore(bytecodeType, getStoreIndex(variableName));
}
public Integer getStoreIndex(String variableName) {
if(storeIndexes.get(variableName) == null){
Integer index = storeIndexes.size()+1;
storeIndexes.put(variableName, index);
}
return storeIndexes.get(variableName);
}
}

View File

@ -0,0 +1,22 @@
package de.dhbwstuttgart.bytecode;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ReferenceType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class TypePlaceholderType extends ReferenceType{
private final TypePlaceholder tph;
public TypePlaceholderType(TypePlaceholder tph) {
super(Constants.T_REFERENCE, "T" + tph.get_Name() + ";");
this.tph = tph;
if(this.tph == null)throw new NullPointerException();
}
public TypePlaceholder getTPH() {
return tph;
}
}

View File

@ -0,0 +1,16 @@
package de.dhbwstuttgart.bytecode;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Utility;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.ReferenceType;
import org.apache.bcel.generic.Type;
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;
}
}

View File

@ -3,6 +3,66 @@ package de.dhbwstuttgart.core;
import java.util.*; import java.util.*;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
public class ConsoleInterface { public class ConsoleInterface {
private static final String directory = System.getProperty("user.dir"); private static final String directory = System.getProperty("user.dir");
private static final Logger log = Logger.getLogger( ConsoleInterface.class.getName() );
/**
* @param args
*/
public static void main(String[] args) {
Menge<String> filenames = new Menge<String>();
for(String file : args){
filenames.add(file);
}
Logger.setStandardConfiguration(new LoggerConfiguration()); // ¤mtliches Logging unterdrücken
run(filenames);
}
public static void run(Menge<String> filenames){
Menge<TypeinferenceResultSet> resultSet = null;
MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration());
try{
/////////////////////////
// Parsen:
/////////////////////////
Menge<SourceFile> sourceFiles = compiler.parse(filenames);
/////////////////////////
// Typrekonstruktion:
/////////////////////////
try{
resultSet = compiler.typeReconstruction(sourceFiles);
}catch(TypeinferenceException texc){
texc.printStackTrace();
throw new DebugException("Fehler bei Typinferenzalgorithmus. Message: "+texc.getMessage());
}
///////////////////////
// Ausgabe:
///////////////////////
if(resultSet == null)System.out.println("Keine Lösung!");
ArrayList<String> resultJavaCodes = new ArrayList<String>();
for(TypeinferenceResultSet result : resultSet){
String javaCode = result.getInterferedClass().printJavaCode(result);
if(!resultJavaCodes.contains(javaCode))resultJavaCodes.add(javaCode);
}
for(String out : resultJavaCodes){
System.out.println("\nMögliche Typisierung:\n\n");
System.out.println(out);
}
}catch(Exception e){
e.printStackTrace();
if(resultSet == null)throw new DebugException("Fehler bei Typinferenzalgorithmus. Message: "+e.getMessage());
}
}
} }

View File

@ -3,4 +3,5 @@ package de.dhbwstuttgart.core;
public interface IItemWithOffset public interface IItemWithOffset
{ {
public int getOffset();
} }

View File

@ -1,10 +1,285 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class MyCompiler { import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.ClassBody;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.IMatchable;
import de.dhbwstuttgart.syntaxtree.type.ITypeContainer;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.FunNInterface;
import de.dhbwstuttgart.typeinference.FunVoidNInterface;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.ParserError;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
public class MyCompiler implements MyCompilerAPI{
// PL: Der Zusammenhang zwischen paralist und vParaOrg muesste // PL: Der Zusammenhang zwischen paralist und vParaOrg muesste
// noch geklaert werden 05-01-07 // noch geklaert werden 05-01-07
public static final int NO_LINENUMBER = -1;
protected static Logger inferencelog = Logger.getLogger(MyCompiler.class.getName());
protected String OutputDir = "";
public Menge<Pair> testPair = null;
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Der private Konstruktor. Es soll von au�en kein Compiler angelegt werden
* ¯Â¿Â½nnen, sondern nur eine API zur Verf�gung gestellt werden.
* @param logger Konfiguration ¼r Debug Ausgabe TODO
*/
private MyCompiler(){
this.init();
}
/**
* Author: rg ¤uerle<br/>
* Stellt eine neue Instanz der CompilerAPI zur Verf�gung.
* Diese Methode sollte von der IDE aus aufgerufen werden,
* um eine Quellcode-Datei zu kompilieren.
* @return Die Compiler-API
*/
public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig){
Logger.setStandardConfiguration(loggerConfig);
return new MyCompiler();
}
/**
* Parst den Quellcode und baut den abstrakten Syntaxbaum auf. Danach wird
* automatisch der von Thomas Ott implementierte Algorithmus
* <code>NewTVar(jclass)</code> (siehe Algorithmus 5.17 TRProg, Martin Pl�micke)
* aufgerufen.
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param reader
* @throws IOException
* @throws JavaParser.yyException
*/
private void parse_backup(Reader reader) throws IOException, JavaParser.yyException{
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Implementierte API-Methoden:
/////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Initialisiert den Compiler
*/
public void init(){
TypePlaceholder.deleteRegistry();
}
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Ruft die Parse-Methode.
* @param file Die Quellcode-Datei
* @throws FileNotFoundException Wenn die Quellcode-Datei nicht existiert.
* @throws IOException Wenn was schief ¯Â¿Â½uft.
* @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt.
*/
public SourceFile parse(File file) throws FileNotFoundException, IOException, JavaParser.yyException{
FileReader fr = new FileReader(file);
SourceFile ret = this.parse2SyntaxTree(fr);
fr.close();
return ret;
}
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* Ruft den Typrekonstruktionsalgorithmus auf.
* @return Die Menge aller ¯Â¿Â½glichen Typkombinationen
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
* ist. @throws CTypeReconstructionException Wenn ein Fehler bei der
* Typrekonstruktion auftritt.
*/
public Menge<TypeinferenceResultSet> typeReconstruction(Menge<SourceFile> m_AbstractSyntaxTree) throws NullPointerException{
inferencelog.info("##########################################", Section.TYPEINFERENCE);
inferencelog.info("# TypeReconstruction-Algorithmus - START #", Section.TYPEINFERENCE);
inferencelog.info("##########################################\n", Section.TYPEINFERENCE);
TypeAssumptions globalAssumptions = makeFunNAssumptions();
Menge<TypeinferenceResultSet> result = new Menge<TypeinferenceResultSet>();
for(SourceFile srcFile : m_AbstractSyntaxTree){
result.addAll(srcFile.typeReconstruction(globalAssumptions));
}
inferencelog.info("#########################################", Section.TYPEINFERENCE);
inferencelog.info("# TypeReconstruction-Algorithmus - ENDE #", Section.TYPEINFERENCE);
inferencelog.info("#########################################\n", Section.TYPEINFERENCE);
return result;
}
/**
* Erstellt die FunN-Assumptions
* Fun0-FunN (momentan ¼r N = 6)
* @return
*/
public static TypeAssumptions makeFunNAssumptions(){
TypeAssumptions ret = new TypeAssumptions();
//Basic Assumptions ¼r die FunN Interfaces:
//TODO: Hier mehr als Fun1-Fun5 implementieren
for(int i = 0; i<6; i++){
FunNInterface funN = new FunNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
for(int i = 0; i<6; i++){
FunVoidNInterface funN = new FunVoidNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
return ret;
}
/**
* Die Main-Funktion, �ber die der Compiler auch per Konsole gestartet
* werden kann.
* @param args Klassendatei
*/
public static void main(String[] args){
MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration());
// Hier koennten ggf. Aenderungen der Ausgabeeinstellungen
// (Debuginfos) vorgenommen werden -> LOG4J
try {
compiler.parse(new File(args[0]));
} catch (FileNotFoundException e) {
System.err.println("Die Datei \""+args[0]+"\" konnte nicht gefunden werden.");
System.exit(0);
} catch (IOException e) {
System.err.println("Fehler beim Parsen:");
System.err.println(e);
System.exit(0);
} catch (yyException e) {
System.err.println("Fehler beim Parsen:");
System.err.println(e);
System.exit(0);
}
}
public void setOutputDir(String dir){
char c = dir.charAt(dir.length()-1);
if (c != '/' & c != '\\') dir = dir + "/";
OutputDir = dir;
// Verzeichnis(se) ggf. anlegen
File f = new File(dir);
f.mkdirs();
}
public String getOutputDir(){
return OutputDir;
}
/**
* Parst den Inhalt einer Datei zu einem Syntaxbaum.
*/
private SourceFile parse2SyntaxTree(Reader fileContent) throws ParserError{
//StringReader reader = new StringReader(fileContent);
//////////////////////////////////////
// Scanner und Parser erzeugen:
//////////////////////////////////////
Scanner scanner = new Scanner(fileContent);
JavaParser parser = new JavaParser();
//////////////////////////////////////
// Parsen ==> Ergebnis: srcFile
//////////////////////////////////////
SourceFile srcFile = null;
try {
srcFile = (SourceFile) parser.yyparse( scanner );
} catch (IOException | yyException e) {
e.printStackTrace();
if(e instanceof yyException)throw new ParserError((yyException)e);
}
//////////////////////////////////////
// Postprocessing:
//////////////////////////////////////
srcFile.parserPostProcessing(null); //Muss mit null aufgerufen werden.
//Fertig:
return srcFile;
}
/**
* Diese Funktion nimmt einen Menge von Dateinamen. Alle diese Dateien werden zu einem SyntaxBaum geparst.
* @return
*/
public Menge<SourceFile> parse(Menge<String> filenames) throws ParserError {
Menge<SourceFile> m_AbstractSyntaxTree = new Menge<SourceFile>();
for(String filename : filenames){
StringBuffer fileData = new StringBuffer();
BufferedReader reader;
try {
reader = new BufferedReader(
new FileReader(filename));
} catch (FileNotFoundException e) {
throw new DebugException("Die Datei "+ filename+" konnte nicht gelesen werden.");
}
char[] buf = new char[1024];
int numRead=0;
try {
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
StringReader srcreader = new StringReader(fileData.toString());
//Den aus der Datei ausgelesenen Quellcode zu einem Syntaxbaum parsen:
m_AbstractSyntaxTree.add(parse2SyntaxTree(srcreader)); // Alle Dateien nacheinander hintereinander anhängen...
}
return m_AbstractSyntaxTree;
}
@Override
public SourceFile parse(String sourceCode) {
return parse2SyntaxTree(new StringReader(sourceCode));
}
@Override
public Menge<ByteCodeResult> generateBytecode(Menge<SourceFile> m_AbstractSyntaxTree, TypeinferenceResults typeinferenceResults) {
//SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement();
//Class parsedClass = parsedFile.KlassenVektor.firstElement();
Menge<ByteCodeResult> ret = new Menge<>();
for(SourceFile sf : m_AbstractSyntaxTree){
ret.addAll(sf.generateBytecode(typeinferenceResults));
}
return ret;
}
} }

View File

@ -2,6 +2,21 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
// ino.end // ino.end
// ino.module.MyCompilerAPI.8570.import
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.parser.JavaParser;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.exceptions.ParserError;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
// ino.class.MyCompilerAPI.21328.description type=javadoc // ino.class.MyCompilerAPI.21328.description type=javadoc
/** /**
* Schnittstellen-Klasse zum Compiler. Diese Klasse soll der * Schnittstellen-Klasse zum Compiler. Diese Klasse soll der
@ -27,5 +42,90 @@ public interface MyCompilerAPI
// ino.method.init.21331.declaration // ino.method.init.21331.declaration
public void init(); public void init();
// ino.end // ino.end
// ino.method.parse.21334.decldescription type=javadoc
/**
* Author: rg ¤uerle<br/>
* Parst eine Quellcodedatei und baut den abstrakten Syntaxbaum auf.
* @param file Die Quellcode-Datei
* @throws FileNotFoundException Wenn die Quellcode-Datei nicht existiert.
* @throws IOException Wenn was schief ¤uft.
* @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt.
*/
// ino.end
// ino.method.parse.21334.declaration
public SourceFile parse(File file)
throws FileNotFoundException, IOException, JavaParser.yyException;
// ino.end
// ino.method.parse.21337.decldescription type=javadoc
/**
* Author: rg ¤uerle<br/>
* Parst einen String und baut den abstrakten Syntaxbaum auf.
* @param srcCode Der zu parsende Quellcode
* @throws IOException Wenn was schief ¤uft.
* @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt.
// ino.end
// ino.method.parse.21337.declaration
public void parse(String srcCode)
throws IOException, JavaParser.yyException;
// ino.end
*/
// ino.method.typeReconstruction.21340.decldescription type=javadoc
/**
* Author: rg ¤uerle<br/>
* Ruft den Typrekonstruktionsalgorithmus auf.
* @return Die Menge aller glichen Typkombinationen
* @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden
* ist. @throws CTypeReconstructionException Wenn ein Fehler bei der
* Typrekonstruktion auftritt.
*/
// ino.end
// ino.method.typeReconstruction.21340.declaration
public Menge<TypeinferenceResultSet> typeReconstruction(Menge<SourceFile> m_AbstractSyntaxTree) throws NullPointerException;
// ino.end
// ino.method.setOutputDir.21349.decldescription type=javadoc
/**
* Author: Juergen Schmiing <br>
* Legt das Ausgabeverzeichnis fuer die class-Files fest.
*/
// ino.end
// ino.method.setOutputDir.21349.declaration
public void setOutputDir(String dir);
// ino.end
// ino.method.getOutputDir.21352.decldescription type=javadoc
/**
* Author: Juergen Schmiing <br>
* Gibt das Ausgabeverzeichnis fuer die class-Files zurueck.
*/
// ino.end
// ino.method.getOutputDir.21352.declaration
public String getOutputDir();
// ino.end
/**
* Parst zusammenhängende JavaKlassen in verschiedenen Dateien.
* @param filenames - Eine Liste von Quellcodedateien, welche gseparst werden sollen
* @return
*/
public Menge<SourceFile> parse(Menge<String> filenames) throws ParserError;
/**
* Parst den SourceCode einer Datei.
* @param sourceCode - SourceCode einer Java-Quellcodedatei
* @return den aus dem sourceCode generierten Syntaxbaum
*/
public SourceFile parse(String sourceCode) throws ParserError;
/**
* Generiert für jede geparste Klasse im SourceFile ein ByteCodeResult.
* Dafür müssen die Schritte Parsen und typeReconstruction ausgeführt werden.
* @return
*/
public Menge<ByteCodeResult> generateBytecode(Menge<SourceFile> m_AbstractSyntaxTree, TypeinferenceResults typeinferenceResults);
} }
// ino.end // ino.end

View File

@ -0,0 +1,165 @@
package de.dhbwstuttgart.logger;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class Logger {
private static LoggerConfiguration standardConfiguration = null;
private static final HashMap<String, Logger> LOGGER_DIRECTORY = new HashMap<>();
private String name;
private final HashMap<Section, java.util.logging.Logger> logger;
private static final LogHistory LOG_HISTORY = new LogHistory();
protected Logger(String name, LoggerConfiguration config) {
this.name = name;
this.logger = new HashMap<>();
if(config != null){
config.forEach((s,o)->{
java.util.logging.Logger log = java.util.logging.Logger.getLogger( name );
log.setLevel(Level.FINE);
log.addHandler(new OutputHandler(o));
logger.put(s, log);
});
}
}
/**
* Logt eine Debug Message, welche zusätzlich einer bestimmten Section zugewiesen wird.
* Dadurch ¤sst sich die DEBUG ausgabe übersichtlicher gestalten.
* @param message
* @param section
*/
public void debug(String message, Section section){
output(message, Level.FINE, section);
}
/**
* Liefert den Logger mit dem angegebenen Namen.
* Üblicherweise wird diese Methode mit dem Namen der Klasse aufgerufen, in welcher der Logger ¤tig ist.
* @param name - Name der Klasse ( Ermittelbar mittels <Klasse>.class.getName() )
* @return
*/
public static Logger getLogger(String name) {
Logger ret;
if(LOGGER_DIRECTORY.containsKey(name)){
ret = LOGGER_DIRECTORY.get(name);
}else{
ret = new Logger(name, standardConfiguration);
LOGGER_DIRECTORY.put(name, ret);
}
return ret;
}
public static SectionLogger getSectionLogger(String name, Section s) {
Logger ret;
if(LOGGER_DIRECTORY.containsKey(name)){
ret = LOGGER_DIRECTORY.get(name);
}else{
ret = new Logger(name, standardConfiguration);
LOGGER_DIRECTORY.put(name, ret);
}
return new SectionLogger(ret,s);
}
protected void output(String msg , Level logLevel, Section section){
Logger.LOG_HISTORY.add(new LogLine(msg, this.name, section, logLevel));
if(logger.containsKey(section)){
java.util.logging.Logger log = logger.get(section);
log.log(logLevel, msg);
}
}
public void info(String message, Section s) {
output(message, Level.INFO, s);
}
public void error(String message, Section s) {
output(message, Level.WARNING, s);
}
/**
* wird hier null übergeben, so wird ¤mtliches Logging unterdrückt.
*/
public static void setStandardConfiguration(LoggerConfiguration config) {
Logger.standardConfiguration = config;
}
public static String getWholeLog(){
String ret = "";
LOG_HISTORY.removeIf((logLine)->logLine==null);
Logger.LOG_HISTORY.sort((log1, log2)->log1.timestamp.compareTo(log2.timestamp));
ret += Logger.LOG_HISTORY.toString();
return ret;
}
}
class OutputHandler extends Handler{
private PrintStream output;
public OutputHandler(PrintStream output){
this.output = output;
}
@Override
public void publish(LogRecord record) {
output.println(record.getMessage());
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
}
class LogHistory extends ArrayList<LogLine>{
private static final long serialVersionUID = -1785228323497318261L;
@Override
public String toString(){
StringBuilder ret = new StringBuilder();
for(LogLine l : this){
ret.append(l.toString() + "\n");
}
return ret.toString();
}
}
class LogLine {
Date timestamp;
String message;
String name;
Section section;
Level level;
LogLine(String msg, String loggerName, Section section, Level logLevel){
this.timestamp = new Date();
this.message = msg;
this.name = loggerName;
this.section = section;
this.level = logLevel;
}
public String toString(){
String ret = "";
ret += name + ": ";
ret += message;
ret += " - " + section.name();
return ret;
}
public String toJSON(){
return "";
}
}

View File

@ -0,0 +1,48 @@
package de.dhbwstuttgart.logger;
import java.io.PrintStream;
import java.util.HashMap;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
public class LoggerConfiguration{
private final HashMap<Section,Menge<PrintStream>> outputs = new HashMap<>(Section.values().length);
public LoggerConfiguration setOutput(Section forSection, PrintStream output){
if(outputs.containsKey(forSection)){
//throw new DebugException("Eine outputStream für Section "+forSection+" ist bereits vorhanden");
if(outputs.get(forSection).equals(output)){
//do nothing
}else{
outputs.get(forSection).add(output);
}
}else{
Menge<PrintStream> outMenge = new Menge<>();
outMenge.add(output);
outputs.put(forSection, outMenge);
}
return this;
}
public void forEach(ConfigurationEvaluater action){
for(Section key : outputs.keySet()){
for(PrintStream out : outputs.get(key)){
action.apply(key, out);
}
}
}
public void mergeConfiguration(LoggerConfiguration config){
for(Section key : config.outputs.keySet()){
for(PrintStream out : config.outputs.get(key)){
this.setOutput(key, out);
}
}
}
}
interface ConfigurationEvaluater {
public void apply(Section s, PrintStream o);
}

View File

@ -0,0 +1,8 @@
package de.dhbwstuttgart.logger;
public enum Section {
TYPEINFERENCE,
PARSER,
CODEGEN,
UNIFY, FINITECLOSURE, ASSUMPTIONS;
}

View File

@ -0,0 +1,26 @@
package de.dhbwstuttgart.logger;
import java.util.logging.Level;
/**
* ¤mtliche Logging Ausgaben werden in die bei der Erstellung des Loggers übergebene Section eingeteilt
* @author janulrich
*
*/
public class SectionLogger {
private Logger log;
private Section section;
protected SectionLogger(Logger logger, Section s){
this.log = logger;
this.section = s;
}
public void debug(String message){
log.debug(message, section);
}
public void info(String string) {
log.info(string, section);
}
public void error(String string) {
log.error(string, section);
}
}

View File

@ -0,0 +1,50 @@
package de.dhbwstuttgart.logger;
import java.util.Stack;
public class Timestamp{
String name;
Stack<Long> timestamps = new Stack<>();
Long accumulatedTime = 0L;
Timestamp(String name){
this.name = name;
}
public void start(){
timestamps.push(System.currentTimeMillis());
}
public Long stop(){
if(timestamps.isEmpty())return 0L;
Long timeStart = timestamps.pop();
Long currentTime = getTime();
Long difference = currentTime-timeStart;
accumulatedTime += difference;
return difference;
}
public Long currentTime(){
if(timestamps.isEmpty())return 0L;
Long timeStart = timestamps.peek();
Long currentTime = getTime();
return currentTime-timeStart;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Timestamp))return false;
return this.name.equals(((Timestamp)obj).name);
}
public String toString(){
String ret = "Zeit für Aktivität "+this.name+": "+this.accumulatedTime;
return ret;
}
private Long getTime(){
return System.currentTimeMillis();
}
}

View File

@ -0,0 +1,74 @@
package de.dhbwstuttgart.logger;
import java.util.HashMap;
import java.util.Stack;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
public class Timewatch {
private static final Timewatch time = new Timewatch();
private final Timestamp startTime;
private Timers timers = new Timers();
private Timewatch(){
//Privater Konstruktor
startTime = new Timestamp("Timewatch Global");
startTime.start();
}
public static Timewatch getTimewatch() {
return time;
}
public String dumpTimeData(){
String ret = "Momentan insgesamt verstrichene Zeit: "+this.startTime.currentTime() +"\n";
ret += timers.toString();
return ret;
}
public Timestamp start(String name){
if(!timers.contains(name)){
Timestamp ret = new Timestamp(name);
timers.add(ret);
ret.start();
return ret;
}else{
//Timer läuft noch... einfach neue Instanz starten:
Timestamp ret = timers.get(name);
ret.start();
return ret;
}
}
}
class Timers{
private Menge<Timestamp> timers = new Menge<>();
public Timestamp get(String name) {
for(Timestamp timer:timers){
if(timer.name.equals(name))return timer;
}
throw new DebugException("Fehler in Timewatch: Der gesuchte Timer "+name+" ist nicht vorhanden.");
}
public void add(Timestamp timer) {
timers.add(timer);
}
public boolean contains(String name) {
return timers.contains(new Timestamp(name));
}
public String toString(){
String ret ="";
for(Timestamp timer : timers){
ret += timer.toString() + "\n";
}
return ret;
}
}

View File

@ -1,11 +1,18 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers; import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Expr; import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.*;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -13,8 +20,15 @@ import java.util.List;
/** /**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/ */
public class Class extends GTVDeclarationContext implements IItemWithOffset, Generic public class Class extends GTVDeclarationContext implements IItemWithOffset, Generic, GenericTypeInsertable
{ {
/**
* Loggerinstanzen
*/
protected static Logger inferencelog = Logger.getLogger("inference");
protected static Logger codegenlog = Logger.getLogger("codegen");
protected static Logger parserlog = Logger.getLogger("parser");
protected Logger typinferenzLog = Logger.getLogger(Class.class.getName());
protected Modifiers modifiers; protected Modifiers modifiers;
protected JavaClassName name; protected JavaClassName name;
@ -26,5 +40,222 @@ public class Class extends GTVDeclarationContext implements IItemWithOffset, Gen
protected boolean isInterface; protected boolean isInterface;
private List<RefType> implementedInterfaces; private List<RefType> implementedInterfaces;
/////////////////////////////////////////////////////////////////////////
// TypeReconstructionAlgorithmus
/////////////////////////////////////////////////////////////////////////
/**
* Ausgangspunkt ¯Â¿Â½r den Typrekonstruktionsalgorithmus. Hier werden zun�chst
* die Mengen von Typannahmen V_fields_methods und V_i erstellt, die als Eingabe
* ¯Â¿Â½r den Algorithmus dienen.<br/>
* (siehe Algorithmus 5.17 TRProg, Martin Pl�micke)
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param supportData
* @param globalAssumptions
* @return Liste aller bisher berechneten, ¯Â¿Â½glichen Typkombinationen
* @throws CTypeReconstructionException
*/
public ConstraintsSet typeReconstruction(TypeAssumptions globalAssumptions)
{
//////////////////////////////
// Und los geht's:
//////////////////////////////
inferencelog.info("Rufe TRStart()...", Section.TYPEINFERENCE);
//////////////////////////////
// Ab hier ...
// @author A10023 - Andreas Stadelmeier:
//////////////////////////////
//Erzeuge Assumptions:
TypeAssumptions assumptions = this.getPrivateFieldAssumptions();
//Globale Assumptions anfügen:
assumptions.add(globalAssumptions);
ConstraintsSet oderConstraints = new ConstraintsSet();
for(Type gparam : this.get_ParaList()){
if(gparam instanceof GenericTypeVar)assumptions.add(((GenericTypeVar)gparam).createAssumptions()); //Constraints ¼r die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
}
for(Type gparam : this.get_ParaList()){
if(gparam instanceof GenericTypeVar)oderConstraints.add(((GenericTypeVar)gparam).TYPE(assumptions)); //Constraints ¼r die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen
}
typinferenzLog.debug("Erstellte Assumptions: "+assumptions, Section.TYPEINFERENCE);
//Gibt es hier eine ClassCastException stimmt etwas grundsätzlich nicht!
//this.superClass = (RefType)this.superClass.TYPE(assumptions, this);
for(Field f:this.getFields()){
oderConstraints.add(f.TYPE(assumptions));
}
typinferenzLog.debug("Erstellte Constraints: "+oderConstraints, Section.TYPEINFERENCE);
return oderConstraints;
}
/**
* Ermittelt alle privaten Felder und Methoden der Klasse und Erstellt eine Assumption ¼r diese.
* Bemerkung: Momentan werden noch alle Felder dieser Klasse zurückgegeben.
* @return Die erstellten TypeAssumptions
*/
private TypeAssumptions getPrivateFieldAssumptions() {
if(this.typeAssumptions != null)return this.typeAssumptions; //Das sorgt dafür, dass die Assumptions nur einmalig generiert werden.
TypeAssumptions assumptions = new TypeAssumptions(this.getName());
for(Field field : this.getFields()){
if(!field.isPublic())assumptions.add(field.createTypeAssumptions(this));
}
this.typeAssumptions = assumptions; //Diese ¼ssen anschließend nicht wieder generiert werden.
return assumptions;
}
/**
* <br/>Author: Martin Pl�micke
* @return
*/
public String toString()
{
return name.toString();
}
public String getTypeInformation(Menge<Method> methodList, Menge<Expr> fieldList){
String ret = this.name+": ";
for(Expr field : fieldList){
ret+=field.getTypeInformation()+"\n";
}
for(Method m : methodList){
ret+=m.getTypeInformation()+"\n";
}
return ret;
}
/**
* Generiert den JavaCode dieser Klasse im Falle ¼r das übergebene resultSet.
* Dem ResultSet entsprechend werden in diesem Java-Code die TypePlaceholder durch die in ResultSet stehenden Typen ersetzt.
* @return Java-Sourcefile
*/
public JavaCodeResult printJavaCode(ResultSet reconstructionResult){
JavaCodeResult ret = new JavaCodeResult("class ");
JavaCodeResult classBodyCode = new JavaCodeResult();
if(this.modifiers!=null)classBodyCode.attach(this.modifiers.printJavaCode(reconstructionResult)).attach(" ");
classBodyCode.attach(this.name + " extends ").attach(this.superClass.printJavaCode(reconstructionResult)).attach("\n");
JavaCodeResult bodyString = new JavaCodeResult("{\n");
for(Field field : this.fielddecl)bodyString.attach( field.printJavaCode(reconstructionResult) ).attach( "\n" );
bodyString.attach("}\n");
classBodyCode.attach(bodyString);
//Zuerst die generischen Parameter ¼r diese Klasse berechnen:
//this.createGenericTypeVars(classBodyCode.getUnresolvedTPH());
if(this.genericClassParameters != null && this.genericClassParameters.size()>0){
ret.attach("<");
Iterator<GenericTypeVar> it = this.genericClassParameters.iterator();
while(it.hasNext()){
GenericTypeVar tph = it.next();
ret.attach(tph.printJavaCode(reconstructionResult));
if(it.hasNext())ret.attach(", ");
}
ret.attach(">");
}
String stringReturn = ret.attach(classBodyCode).toString();
return new JavaCodeResult(stringReturn);
}
public int getOffset(){
return this.offset;
}
/**
* Erstellt einen RefType, welcher auf diese Klasse verweist
* Ersetzt alle Generischen Variablen in der Parameterliste mit TPH
* @return
*/
public RefType getType() {
return new RefType(this.getName().toString(), this.get_ParaList(),this, 0);
}
/**
* Ermittelt die Sichtbaren Felder und Methoden der Klasse.
* (Momentan sind im Projekt alle Felder und Methoden "package private", da der Parser keine Access-Modifier einlesen kann.
* @return
*/
public TypeAssumptions getPublicFieldAssumptions() {
TypeAssumptions ret = new TypeAssumptions();//this.getPrivateFieldAssumptions();
ret.addClassAssumption(new ClassAssumption(this));
for(Field f : this.getFields()){
if(f.isPublic())ret.add(f.createTypeAssumptions(this));
}
for(GenericTypeVar gtv : this.getGenericParameter()){
ret.add(gtv.createAssumptions());
}
return ret;
}
@Override
public boolean equals(Object obj){
if(!(obj instanceof Class))return false;
Class cl = (Class) obj;
if(!(cl.getName().equals(this.getName())))return false;
return true;
}
@Override
public GenericDeclarationList getGenericParameter() {
return this.genericClassParameters;
}
@Override
public String getDescription(){
return "class "+this.getName();
}
@Override
public void setGenericParameter(GenericDeclarationList params) {
this.genericClassParameters = params;
}
@Override
public String getGenericVarDeclarationString(String genericVarDeclaration) {
if(this.genericClassParameters != null){
return ", "+genericVarDeclaration;
}else{
return "<"+genericVarDeclaration+">";
}
}
@Override
public int getGenericVarDeclarationOffset(){
// Falls Generische Parameterliste vorhanden, hier Wert der Liste zurückgegebn
if(this.genericClassParameters != null){
return this.genericClassParameters.getEndOffset();
}else{
return this.offset;
}
}
/**
* Die Super Klasse dieser Klasse.
* @return null ¼r Klasse Object
*/
public RefType getSuperClass(){
return this.superClass;
}
@Override
public boolean isClass() {
return true;
}
public boolean isInterface(){
return isInterface;
}
} }

View File

@ -1,16 +1,95 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.MethodGenerator;
import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.syntaxtree.type.Void;
public class Constructor extends Method { public class Constructor extends Method {
/**
* Parser kann nicht zwischen einem Konstruktor und einer Methode unterscheiden.
public Constructor(String name, RefType returnType, ParameterList parameterList, Block block, GenericDeclarationList gtvDeclarations, int offset) { * Diese Klasse beherbegt den als Methode geparsten Konstruktor und wandelt sein verhalten zu dem eines Konstruktors ab.
super(name, returnType, parameterList, block, gtvDeclarations, offset); */
public Constructor(Method methode, Class parent){
super(methode.get_Name(), methode.getType(), methode.getParameterList(),
methode.get_Block(), methode.getGenericDeclarationList(), methode.getOffset());
//Sicherstellen, dass das erste Statement in der Methode ein SuperCall ist:
if(this.get_Block().get_Statement().size() <1 || ! (this.get_Block().get_Statement().get(0) instanceof SuperCall)){
this.get_Block().statements.add(0, new SuperCall(this.get_Block()));
this.parserPostProcessing(parent);
}
} }
@Override
public TypeAssumptions createTypeAssumptions(Class classmember) {
this.parent = classmember;
Class parentClass = classmember;
TypeAssumptions ret = new TypeAssumptions();
ret.addAssumption(new ConstructorAssumption(this, parentClass));
return ret;
}
public void genByteCode(ClassGenerator cg, InstructionList fieldInitializations){
DHBWConstantPoolGen _cp = cg.getConstantPool();
InstructionList il = new InstructionList(); //sollte nicht new sein sondern aus Block kommen
MethodGenerator method = new MethodGenerator(Constants.ACC_PUBLIC, this.getType().getBytecodeType(cg, null),
this.parameterlist.getBytecodeTypeList(cg,null) , this.parameterlist.getParameterNameArray(),
"<init>", cg.getClassName(), il, _cp);
//FieldInitializations an Block anfügen
Block block = this.get_Block();
if(! (block.statements.get(0) instanceof SuperCall)){
throw new DebugException("Fehlender SuperCall im Konstruktor");
}
//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(), null));
}
@Override
public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
this.genByteCode(cg, new InstructionList());
}
// super statement muss drin sein
// stmt genByteCode + im block genByteCode implementieren & dann Hierarchie ausprobieren
// de.dhbw.systanxtree.stmts supercall
// Aufrufhierarchie: Class->Felder->Konstruktor->Methode innerhalb Konstruktor->Block->Statements (in diesem Fall nur super())->hier wird bytecode f<EFBFBD>r superaufruf generiert
@Override
public void parserPostProcessing(SyntaxTreeNode parent){
super.parserPostProcessing(parent);
if(this.parameterlist != null){
for(FormalParameter fp : this.parameterlist){
fp.parserPostProcessing(this);
}
}
for(GenericTypeVar gtv : this.getGenericParameter()){
gtv.parserPostProcessing(this);
}
}
@Override
public JavaClassName getTypeName() {
return this.getType().getName();
}
} }

View File

@ -1,18 +1,130 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefType; import org.apache.bcel.generic.ClassGen;
public abstract class Field extends GTVDeclarationContext implements Generic { import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.GenericTypeInsertable;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.Typeable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
public abstract class Field extends GTVDeclarationContext implements TypeInsertable, Typeable, Generic, GenericTypeInsertable{
private String name; private String name;
protected Type typ;
private GenericDeclarationList genericParameters; private GenericDeclarationList genericParameters;
public Field(String name, RefType type, int offset){ public Field(String name, Type type, int offset){
super(offset);
this.name = name; this.name = name;
this.typ = type;
}
@Override
public void setOffset(int offset){
this.offset = offset;
}
@Override
public int getOffset(){
return this.offset;
}
@Override
public Type getType() {
return typ;
}
@Override
public Menge<GenericTypeVar> getGenericParameter() {
Menge<GenericTypeVar> ret = new Menge<>();
if(this.genericParameters == null)return ret;
ret.addAll(this.genericParameters.getGTVList());
return ret;
}
GenericDeclarationList getGenericDeclarationList(){
return this.genericParameters;
} }
public abstract JavaCodeResult printJavaCode(ResultSet resultSet);
/**
* Diese Methode generiert die Assumptions ¼r dieses Feld der Klasse classmember
* @param classmember
* @return
*/
public abstract TypeAssumptions createTypeAssumptions(Class classmember);
public abstract ConstraintsSet TYPE(TypeAssumptions publicAssumptions);
public String getIdentifier() {
return name;
}
@Override
public String getDescription(){
return this.getIdentifier();
}
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph), resultSet);
}
public boolean isPublic() {
//TODO: momentan ist jedes Feld public!
return true;
}
@Override
public String getGenericVarDeclarationString(String genericVarDeclaration) {
if(this.genericParameters != null){
return ", "+genericVarDeclaration;
}else{
return "<"+genericVarDeclaration+">";
}
}
@Override
public int getGenericVarDeclarationOffset(){
// Falls Generische Parameterliste vorhanden, hier Wert der Liste zurückgegebn
if(this.genericParameters != null){
return this.genericParameters.getEndOffset();
}else{
return this.offset;
}
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<>();
if(this.getType()!=null)ret.add(this.getType());
ret.addAll(this.getGenericParameter());
return ret;
}
@Override
public void setGenericParameter(GenericDeclarationList params) {
this.genericParameters = params;
}
@Override
public boolean isClass() {
return false;
}
} }

View File

@ -7,8 +7,24 @@ import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.Const; import org.apache.bcel.Const;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.statement.Expr; import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
/** /**
* Eine Feldinitialisation steht ¼r eine Felddeklaration mit gleichzeitiger Wertzuweisung * Eine Feldinitialisation steht ¼r eine Felddeklaration mit gleichzeitiger Wertzuweisung
* Beispiel: 'public Feld FeldVar = FeldWert;' * Beispiel: 'public Feld FeldVar = FeldWert;'
@ -23,10 +39,109 @@ public class FieldDeclaration extends Field{
* Dieser Konstruktor der FieldDeclaration erstellt den Syntaxknoten vollständig. * Dieser Konstruktor der FieldDeclaration erstellt den Syntaxknoten vollständig.
* Kein nachträgliches hinzfügen von Informationen oder aufrufen von parserPostProcessing ist notwendig. * Kein nachträgliches hinzfügen von Informationen oder aufrufen von parserPostProcessing ist notwendig.
*/ */
public FieldDeclaration(String name, RefType typ, Expr value){ public FieldDeclaration(String name, Type typ, Expr value){
super(name, typ, 0);//Dieser Deklarator wird nicht vom Parser aufgerufen. Dadurch gibt es auch keinen Offset super(name, typ, 0);//Dieser Deklarator wird nicht vom Parser aufgerufen. Dadurch gibt es auch keinen Offset
this.wert = value; this.wert = value;
} }
public Expr getWert(){
return this.wert;
}
@Override
public String toString()
{
if(getWert()!=null)return super.toString() + "=" + getWert().toString();
return super.toString();
}
public JavaCodeResult printJavaCode(TypeinferenceResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
JavaCodeResult toAttach = this.getType().printJavaCode(resultSet).attach(" ").attach( this.getIdentifier());
if(this.wert!=null)toAttach.attach(" = ").attach(this.getWert().printJavaCode(resultSet) );
toAttach.attach( ";");
ret.attach(toAttach);
return ret;
}
@Override
public TypeAssumptions createTypeAssumptions(Class classmember) {
//////////////////////////////
//Felder:
//////////////////////////////
TypeAssumptions assumptions = new TypeAssumptions();
/*
* Der Feld-Assumption muss ein TPH als Typ hinzugefügt werden, falls er Typlos initialisiert wurde. Dies kann auch der Type-Algorithmus der Inst/FieldVar - Klasse machen.
* Wird das Feld mit einem Typ initialisiert so muss dieser auch in die Assumptions.
*/
if(this.getType() == null)throw new TypeinferenceException("Der Typ eines Feldes darf nicht null sein", this);
//assumptions.add(TypeAssumptions.createFieldVarAssumption(classmember.getName(), this.getName(), this.getType()));
assumptions.addAssumption(new FieldAssumption(this,classmember));
return assumptions;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = super.getChildren();
if(this.wert!=null)ret.add(this.wert);
return ret;
}
@Override
public ConstraintsSet TYPE(TypeAssumptions publicAssumptions) {
if(this.wert == null && (this.getType() == null || this.getType() instanceof TypePlaceholder))
throw new TypeinferenceException("Typlose Felder müssen mit Wert initialisiert werden", this);
ConstraintsSet ret = new ConstraintsSet();
TypeAssumptions localAssumptions = publicAssumptions.clone();
for(GenericTypeVar gp : this.getGenericParameter()){
localAssumptions.add(gp.createAssumptions());
}
for(GenericTypeVar gp : this.getGenericParameter()){
gp.TYPE(localAssumptions);
}
//TypeCheck, falls es sich um einen RefType handelt:
Type thisType = this.getType();
UndConstraint c1 = ConstraintsSet.createSingleConstraint(thisType, thisType);
ret.add(c1); //Damit die TypVariable des Felds in den Constraints auftaucht
if(this.wert!=null){
//Falls bei der Deklaration ein Wert zugewiesen wird, verhält sich das Constraintserzeugen wie bei dem Assign-Statement:
ret.add(this.wert.TYPEExpr(localAssumptions));
ret.add(ConstraintsSet.createSingleConstraint(this.wert.getType().TYPE(localAssumptions,this), thisType));
}
return ret;
}
/**
* Das besondere bei genByteCode einer FieldDeclaration ist, dass ein InstructionList zurückgegeben wird.
* Dieser muss in jeden Konstruktor eingefügt werden um das Feld zu initialisieren.
* @param cg
* @return - Die InstructionList, welche das Feld initialisiert
*/
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
//Das Feld an die Klasse anfügen:
FieldGen field = new FieldGen(0, this.getType().getBytecodeType(cg, rs), this.getDescription(), cg.getConstantPool());
field.addAttribute(cg.getInstructionFactory().createSignatureAttribute(this.getType().getBytecodeSignature(cg, rs)));
cg.addField(field.getField());
//Die Felddekleration an den Konstruktor anhängen:
InstructionList il = new InstructionList();
il.append(new This(this).genByteCode(cg, rs));
if(wert != null){
il.append(this.wert.genByteCode(cg, rs));
}
FieldInstruction putFieldInstruction =
cg.getInstructionFactory().createFieldAccess(cg.getClassName(),
this.getDescription(), this.getType().getBytecodeType(cg, rs), Const.PUTFIELD);
il.append(putFieldInstruction );
return il;
}
} }

View File

@ -1,15 +1,89 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.typeinference.Menge;
public class FormalParameter extends SyntaxTreeNode import java.util.List;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.Typeable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class FormalParameter extends SyntaxTreeNode implements Typeable, TypeInsertable
{ {
private RefType type; private Type type;
private String name; private String name;
protected static Logger inferencelog = Logger.getLogger("inference");
public FormalParameter(String name, RefType type, int offset){ public FormalParameter(String name, Type type, int offset){
super(offset);
this.name = name; this.name = name;
this.type = type; this.type = type;
} }
@Override
public boolean equals(Object object) {
//if(!super.equals(object))return false; //Nicht die Position im SyntaxBaum prüfen.
if(!(object instanceof FormalParameter))return false;
FormalParameter equals = (FormalParameter)object;
if((this.type==null)!=(equals.type == null))return false;
if(this.type != null){
return this.type.equals(equals.type);
}
return true;
}
public String getIdentifier()
{
return name;
}
public Type getType()
{
return type;
}
@Override
public String toString(){
String ret = "";
if(this.getType() != null)ret += this.getType().toString();
if(this.getIdentifier() != null)ret += " "+getIdentifier();
return ret;
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
if(this.getType() != null)ret.attach(this.getType().printJavaCode(resultSet));
if(this.getIdentifier() != null)ret.attach(" "+getIdentifier());
return ret;
}
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
if(this.getOffset()<=0)return null;
Type t = resultSet.getTypeEqualTo(tph);
return new TypeInsertPoint(this, this, t, resultSet);
}
@Override
public String getDescription(){
String ret = "";
if(this.getType() != null && !(this.getType() instanceof TypePlaceholder)){
ret += this.getType().toString();//getBytecodeSignature(null, null);
}
return ret+this.getIdentifier();
}
} }

View File

@ -5,4 +5,12 @@ package de.dhbwstuttgart.syntaxtree;
* dass bei seiner Deklaration auch Generische Typvariablen deklariert wurden. * dass bei seiner Deklaration auch Generische Typvariablen deklariert wurden.
*/ */
public abstract class GTVDeclarationContext extends SyntaxTreeNode { public abstract class GTVDeclarationContext extends SyntaxTreeNode {
public GTVDeclarationContext(int offset) {
super(offset);
}
@Override
public GTVDeclarationContext getGTVDeclarationContext(){
return this;
}
public abstract boolean isClass();
} }

View File

@ -1,9 +1,15 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import java.util.Iterator;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
/** /**
* Wird von allen Klassen implementiert, welche generische Parameter halten nnen. (Class, Method und Field) * Wird von allen Klassen implementiert, welche generische Parameter halten nnen. (Class, Method und Field)
* @author janulrich * @author janulrich
* *
*/ */
public interface Generic { public interface Generic {
public Iterable<GenericTypeVar> getGenericParameter();
} }

View File

@ -1,7 +1,12 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import java.util.*; import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
/** /**
* Stellt eine Deklarations-Liste von Generischen Variablen dar. * Stellt eine Deklarations-Liste von Generischen Variablen dar.
@ -12,9 +17,10 @@ import java.util.*;
public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<GenericTypeVar>{ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<GenericTypeVar>{
private int offsetOfLastElement; private int offsetOfLastElement;
private List<GenericTypeVar> gtvs = new ArrayList<>(); private List<GenericTypeVar> gtvs = new Menge<>();
public GenericDeclarationList(List<GenericTypeVar> values, int endOffset) { public GenericDeclarationList(List<GenericTypeVar> values, int endOffset) {
super(endOffset);
gtvs = values; gtvs = values;
this.offsetOfLastElement = endOffset; this.offsetOfLastElement = endOffset;
} }
@ -23,8 +29,34 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
return offsetOfLastElement; return offsetOfLastElement;
} }
@Override
public int getOffset() {
return getEndOffset();
}
@Override @Override
public Iterator<GenericTypeVar> iterator() { public Iterator<GenericTypeVar> iterator() {
return null; return this.gtvs.iterator();
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<>();
for(GenericTypeVar gtv : gtvs){
ret.add(gtv);
}
return ret;
}
public int size() {
return gtvs.size();
}
public void add(GenericTypeVar t) {
this.gtvs.add(t);
}
public List<GenericTypeVar> getGTVList() {
return this.gtvs;
} }
} }

View File

@ -1,6 +1,10 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -26,6 +30,7 @@ public class GenericTypeVar extends SyntaxTreeNode
public GenericTypeVar(String s, List<RefType> bounds, int offset, int endOffset) public GenericTypeVar(String s, List<RefType> bounds, int offset, int endOffset)
{ {
super(offset);
name = s; name = s;
if(bounds != null)for(RefType t : bounds){ if(bounds != null)for(RefType t : bounds){
//if(t!=null)this.extendVars.add(t); //if(t!=null)this.extendVars.add(t);
@ -49,4 +54,19 @@ public class GenericTypeVar extends SyntaxTreeNode
return "BoGTV " + this.name; return "BoGTV " + this.name;
} }
@Override
public List<SyntaxTreeNode> getChildren() {
List<SyntaxTreeNode> ret = new ArrayList<>();
ret.addAll(this.bounds);
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
throw new NotImplementedException();
}
public String getName() {
return name;
}
} }

View File

@ -4,15 +4,32 @@ package de.dhbwstuttgart.syntaxtree;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.bytecode.MethodGenerator;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers; import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.modifier.Static; import de.dhbwstuttgart.syntaxtree.modifier.Static;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
// ino.class.Method.23482.declaration // ino.class.Method.23482.declaration
/** /**
@ -23,22 +40,331 @@ import de.dhbwstuttgart.syntaxtree.statement.Block;
* @author janulrich * @author janulrich
* *
*/ */
public class Method extends Field implements IItemWithOffset public class Method extends Field implements IItemWithOffset, TypeInsertable
{ {
private Block block; private Block block;
public ParameterList parameterlist = new ParameterList(null); public ParameterList parameterlist = new ParameterList();
private ExceptionList exceptionlist; private ExceptionList exceptionlist;
private Type returntype;
private String name; private String name;
private List<String> types_in_parameterlist = new ArrayList<>(); private Menge<String> types_in_parameterlist = new Menge<String>();
private Modifiers modifiers; private Modifiers modifiers;
protected static Logger inferencelog = Logger.getLogger("inference");
protected static Logger parserlog = Logger.getLogger("parser");
public Method(String name, RefType returnType, ParameterList parameterList, Block block, /**
*
* @param name
* @param returnType
* @param params
* @param block - use null to create abstract method
* @param offset
*/
public Method(String name, Type returnType, ParameterList params, Block block, int offset) {
this(name, returnType, params, new ExceptionList(), block, offset);
}
public Method(String name, Type returnType, ParameterList params, ExceptionList exceptions, Block block, int offset){
super(name, generateMethodType(returnType, params), offset);
}
public Method(String name, Type returnType, ParameterList parameterList, Block block,
GenericDeclarationList gtvDeclarations, int offset) { GenericDeclarationList gtvDeclarations, int offset) {
super(name, returnType, offset); this(offset);
this.name = name; this.name = name;
this.parameterlist = parameterList; this.parameterlist = parameterList;
this.block = block; this.block = block;
this.setGenericParameter(gtvDeclarations);
this.returntype = returnType;
} }
public JavaClassName getTypeName()
{
if (this.getType() == null)
return null;
else
return this.getType().getName();
}
public Block get_Block()
{
return block;
}
public ParameterList getParameterList()
{
return this.parameterlist;
}
/**
* Author: Jrg Buerle<br/>
*
* @return Die Anzahl der Methoden-Paramater
*/
public int getParameterCount()
{
if (this.getParameterList() == null)
return 0;
else
return this.getParameterList().getParameterCount();
}
public ExceptionList get_ExceptionList()
{
// otth: gibt die Exceptionliste zurueck
return this.exceptionlist;
}
public int getOverloadedID()
{
return (overloadedID);
}
public void setOverloadedID(int overloadedID)
{
this.overloadedID = overloadedID;
}
public String get_Name()
{
return name;
}
public Menge get_Type_Paralist()
{
return types_in_parameterlist;
}
public int getLineNumber()
{
return m_LineNumber;
}
public void setLineNumber(int lineNumber)
{
m_LineNumber = lineNumber;
}
public int getOffset()
{
return m_Offset;
}
public int getVariableLength()
{
return get_Name().length();
}
public void setOffset(int Offset)
{
m_Offset = Offset;
}
/**
* <br>
* Author: Jrg Buerle
*
* @return
*/
public int getTypeLineNumber()
{
return this.getLineNumber();
}
/**
* <br/>
* Author: Martin Pl�micke
*
* @return
*/
public String toString()
{
return this.getType() + " " + this.get_Name() + ((block != null) ? block.toString() : "");
}
/**
* Legt fuer die ByteCodeGen fest, ob Bytecode innerhalb der Methode
* generiert wird.
*/
public void setAbstract(boolean b)
{
isAbstract = b;
}
/**
* Gibt zurueck, ob ByteCode innerhabl der Methode generiert wird.
*/
public boolean isAbstract()
{
return isAbstract;
}
public ConstraintsSet TYPE(TypeAssumptions ass) {
ConstraintsSet ret = new ConstraintsSet();
TypeAssumptions localAss = new TypeAssumptions();
localAss.add(ass); // Die globalen Assumptions anhängen
// Generische Parameterdeklarationen den Assumptions anfügen:
for (GenericTypeVar gtv : this.getGenericParameter()) {
localAss.add(gtv.createAssumptions());
}
for (GenericTypeVar gtv : this.getGenericParameter()) {
ret.add(gtv.TYPE(localAss));
}
// TypeCheck, falls es sich um einen RefType handelt:
this.returntype = this.returntype.checkTYPE(localAss, this);
// Die Parameter zu den Assumptions hinzufügen:
if (this.parameterlist != null)
for (FormalParameter param : this.parameterlist) {
localAss.addAssumption(new ParameterAssumption(param));
}
ret.add(this.block.TYPEStmt(localAss));
// eine Verknüpfung mit der Type Assumption aus dem Assumption Set
// und dem ermittelten Typ der Methode:
ret.add(ConstraintsSet.createSingleConstraint(this.block.getType().TYPE(localAss, this), this.returntype.TYPE(localAss, this)));
return ret;
}
/**
* @author Andreas Stadelmeier, a10023
* @return die TypInformationen der Statements dieser Methode.
*/
public String getTypeInformation() {
if (this.parameterlist != null)
return "Methode " + this.get_Name() + " Parameter: "
+ this.parameterlist.getTypeInformation() + ", Block: "
+ this.block.getTypeInformation();
return "Methode " + this.get_Name() + " : " + this.getType()
+ ", Block: " + this.block.getTypeInformation();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
ret.attach(this.getType().printJavaCode(resultSet)).attach(" ")
.attach(this.get_Name()).attach("(")
.attach(this.getParameterList().printJavaCode(resultSet))
.attach(")\n");
ret.attach(this.block.printJavaCode(resultSet));
return ret;
}
/**
* Liefert die MethodAssumption zu dieser Methode
*/
@Override
public TypeAssumptions createTypeAssumptions(Class classmember) {
Class parentClass = classmember;// this.getParentClass();
TypeAssumptions ret = new TypeAssumptions();
ret.addAssumption(new MethodAssumption(this, parentClass));
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.block);
ret.add(this.parameterlist);
ret.addAll(this.getGenericParameter());
ret.add(this.returntype);
return ret;
}
/**
* Der Typ einer Methode ist ihr Returntype
*/
@Override
public Type getType() {
// Methode und Block teilen sich einen ReturnType:
return this.returntype;
}
public static Method createEmptyMethod(Block withBlock, String withSignature) {
Method ret = Method.createEmptyMethod(withSignature, parent);
ret.set_Block(withBlock);
return ret;
}
public static Method createEmptyMethod(String withSignature) {
Block block = new Block(new List<Statement>());
Method ret = new Method(withSignature, new de.dhbwstuttgart.syntaxtree.type.Void(0), new ParameterList(), block, new EmptyGenericDeclarationList(), 0);
DImethod.set_Name(withSignature);
ret.set_DeclId(DImethod);
Block tempBlock = new Block();
ret.set_Block(tempBlock);
ret.parserPostProcessing(parent);
return ret;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Method))
return false;
Method equals = (Method) obj;
if ((this.returntype != null && equals.returntype == null))
return false;
if ((this.returntype == null && equals.returntype != null))
return false;
if (this.returntype != null && equals.returntype != null)
if (!this.returntype.equals(equals.returntype))
return false;
if (!this.parameterlist.equals(equals.parameterlist))
return false;
return super.equals(obj);
}
public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
List<TypeinferenceResultSet> typeInterferenceResults = resultSets.getTypeReconstructions(this, cg);
DHBWInstructionFactory _factory = cg.getInstructionFactory();
for(TypeinferenceResultSet t: typeInterferenceResults){
addMethodToClassGenerator(cg, _factory, t, classObj);
}
}
<<<<<<< HEAD
private void addMethodToClassGenerator(ClassGenerator cg, DHBWInstructionFactory _factory, TypeinferenceResultSet t, Class parentClass) {
=======
private void addMethodToClassGenerator(ClassGenerator cg, DHBWInstructionFactory _factory, TypeinferenceResultSet t) {
>>>>>>> refactoring
DHBWConstantPoolGen _cp = cg.getConstantPool();
InstructionList il = new InstructionList();
ArrayList<org.apache.bcel.generic.Type> argumentTypes = new ArrayList<org.apache.bcel.generic.Type>();
ArrayList<String> argumentNames = new ArrayList<String>();
if(this.parameterlist != null && this.parameterlist.size() > 0){
generateArgumentList(argumentTypes, argumentNames, cg, t);
}
short constants = Constants.ACC_PUBLIC;
if(this.modifiers != null && this.modifiers.includesModifier(new Static())) constants += Constants.ACC_STATIC;
Type returnType = this.getType();
MethodGenerator method = new MethodGenerator(constants, returnType.getBytecodeType(cg, t),
<<<<<<< HEAD
argumentTypes.toArray(new org.apache.bcel.generic.Type[parameterlist.size()])
, argumentNames.toArray(new String[parameterlist.size()]), this.get_Name(), parentClass.name.toString(), il, _cp);
=======
argumentTypes.toArray(new org.apache.bcel.generic.Type[parameterlist.size()]) ,
argumentNames.toArray(new String[parameterlist.size()]), this.get_Method_Name(),
getParentClass().name.toString(), il, _cp);
>>>>>>> refactoring
cg.setMethodeGenerator(method);
cg.addMethod(method.createMethod(cg, getParameterList(), returnType, get_Block(), t));
}
private void generateArgumentList(ArrayList<org.apache.bcel.generic.Type> argumentTypes, ArrayList<String> argumentNames, ClassGenerator cg, TypeinferenceResultSet t) {
for(FormalParameter parameter : this.parameterlist){
argumentTypes.add(parameter.getType().getBytecodeType(cg, t));
argumentNames.add(parameter.getIdentifier());
}
}
} }

View File

@ -1,14 +1,21 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.typeinference.Menge;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
public class ParameterList extends SyntaxTreeNode implements Iterable<FormalParameter> public class ParameterList extends SyntaxTreeNode implements Iterable<FormalParameter>
{ {
public List<FormalParameter> formalparameter; public List<FormalParameter> formalparameter = new Menge<FormalParameter>();
public ParameterList(List<FormalParameter> params){ public ParameterList(List<FormalParameter> params){
this.formalparameter = params; this.formalparameter = params;
@ -26,9 +33,88 @@ public class ParameterList extends SyntaxTreeNode implements Iterable<FormalPara
{ {
return formalparameter; return formalparameter;
} }
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* @return Die Anzahl der Parameter
*/
public int getParameterCount()
{
return formalparameter.size();
}
public String toString(){
if(formalparameter == null)return "[]"; //"Leere Parameterliste";
//String ret = "ParameterListe, "+formalparameter.size()+" Einträge [ ";
String ret = " [ ";
for(FormalParameter param : this.formalparameter){
ret += param.toString()+", ";
}
return ret + "]";
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
Iterator<FormalParameter> it = this.formalparameter.iterator();
while(it.hasNext()){
FormalParameter param = it.next();
ret.attach(param.printJavaCode(resultSet));
if(it.hasNext())ret.attach(", ");
}
//if(this.formalparameter.size()>0)ret = ret.substring(0, ret.length() - 2);
return ret;
}
@Override @Override
public Iterator<FormalParameter> iterator() { public Iterator<FormalParameter> iterator() {
return null; return this.formalparameter.iterator();
} }
@Override
public boolean equals(Object obj) {
if(!(obj instanceof ParameterList))return false;
ParameterList equals = (ParameterList)obj;
if((this.formalparameter == null )!=(equals.formalparameter==null))return false;
if(this.formalparameter!=null)return this.formalparameter.equals(equals.formalparameter);
return true;
}
@Override
public int getOffset() {
if(formalparameter == null || formalparameter.size()==0)return 0;
return formalparameter.get(0).getOffset();
}
@Override
public List<? extends SyntaxTreeNode> getChildren() {
return formalparameter;
}
public int size() {
return this.formalparameter.size();
}
public org.apache.bcel.generic.Type[] getBytecodeTypeList(ClassGenerator cg, TypeinferenceResultSet rs){
org.apache.bcel.generic.Type[] ret = new org.apache.bcel.generic.Type[formalparameter.size()];
int i = 0;
for(FormalParameter f : formalparameter){
ret[i] = f.getType().getBytecodeType(cg, rs);
i++;
}
return ret;
}
public String[] getParameterNameArray() {
String[] ret = new String[formalparameter.size()];
int i = 0;
for(FormalParameter f : formalparameter){
ret[i] = f.getIdentifier();
i++;
}
return ret;
}
} }

View File

@ -1,20 +1,45 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import java.util.*; import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import de.dhbwstuttgart.typeinference.*;
import java.util.stream.Stream; import java.util.stream.Stream;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.Unifikationsalgorithmus;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class SourceFile extends SyntaxTreeNode public class SourceFile extends SyntaxTreeNode
{ {
protected static Logger codegenlog = Logger.getLogger("codegen");
protected static Logger inferencelog = Logger.getLogger("inference");
private String pkgName; private String pkgName;
public List<Class> KlassenVektor = new ArrayList<>(); public List<Class> KlassenVektor = new Menge<Class>();
private List<JavaClassName> imports; private List<JavaClassName> imports;
/** /**
@ -25,6 +50,500 @@ public class SourceFile extends SyntaxTreeNode
this.KlassenVektor = classDefinitions; this.KlassenVektor = classDefinitions;
} }
/**
* PL 2014-10-25
* schnitt1 checkt ob die Typeplaceholders aus in den Elemeneten aus vars enthalten sind
* ¼ckgabe ist die Menge der Indizies von vars der Schnittmengen mit var nicht leer sind.
* @param var
* @param vars
* @param indexe
* @return
*/
static Menge<Integer> schnitt1 (Menge<PlaceholderType> var, Menge<Menge<PlaceholderType>> vars, Menge<Integer> indexe) {
int j = -1;
for (Menge<PlaceholderType> varelems : vars) {
j++;
if (varelems != null) {
if (var.stream().map(x -> varelems.contains(x)).reduce(false, (a,b) -> (a || b))
&& (!indexe.contains(j)))
{
Menge<PlaceholderType> rekvarelements = vars.elementAt(j);
vars.setElementAt(null, j);//Element erledigt muss nicht nochmals bearbeitet werden.
indexe.addElement(j);
indexe = schnitt1(rekvarelements, vars, indexe);
}
}
}
return indexe;
}
/**
* Bildet Schnittmengen der Mengen von Typeplaceholders
* Rueckgabe ist die Menge der Menge von Indizies die Schnittmengen sind.
* @param vars
* @return
*/
public static Menge<Menge<Integer>> schnitt (Menge<Menge<PlaceholderType>> vars) {
Menge<Menge<Integer>> ret = new Menge<>();
int i = -1;
for (Menge<PlaceholderType> var : vars) {
i++;
if (var != null) {//Element wurde noch bearbeitet
Menge<Integer> indexe = new Menge<>();
indexe.add(i);
ret.add(schnitt1(var, vars, indexe));
}
}
return ret;
}
public static Set<Set<UnifyPair>> cartesianProduct(List<UnifyPair> constraints, FiniteClosure finiteClosure){
//IDEE: Man bildet Zusammenhangskomponenten von Paaren, die gemeinsame Variablen haben
// und unifizert nur die Zusammenhangskomponenten in Schritten 1 - 5
//Schritt 1: Alle Variablen in den Paaren von Elementen einsammeln
Menge<Menge<PlaceholderType>> constraintsclonevars = constraints.stream().map(p -> {Menge<PlaceholderType> TPHs = new Menge<>();
TPHs.addAll(p.getInvolvedPlaceholderTypes());
TPHs.addAll(p.getInvolvedPlaceholderTypes());
return TPHs;}
).collect(Menge::new, Menge::add, Menge::addAll);
//Schritt 2: Schnittmengen jedes Elements mit jedem Elememt von vars bilden und dann index zusammenfassen
//in indexset sind dann die Mengen von Indizes enthalten, die gemeisam unifiziert wreden ¼ssen
Menge<Menge<Integer>> indexeset = new Menge<>();
if (constraintsclonevars != null && constraintsclonevars.size()>0) {
indexeset = SourceFile.schnitt(constraintsclonevars);
}
//Schritt 3: Umwandlung der Indizes in die zugehoerigen Elemente
// In streamconstraintsclone sind die Mengen von Paar enthalten die unifiziert werden muessen
Stream<Menge<UnifyPair>> streamconstraintsclone = indexeset.stream().<Menge<UnifyPair>>map(x -> x.stream()
.<UnifyPair>map(i -> constraints.get(i))
.<Menge<UnifyPair>>collect(Menge::new, Menge::add, Menge::addAll));
//Menge<Menge<Pair>> vecconstraintsclone = streamconstraintsclone.collect(Menge::new, Menge::add, Menge::addAll);
//System.out.println();
//Schritt 4: Unifikation
Menge<Set<Set<UnifyPair>>> vecunifyResult =
//streamconstraintsclone.map(x -> Unify.unify(x, finiteClosure)).collect(Menge::new, Menge::add, Menge::addAll);
//DEBUG-Variante
streamconstraintsclone.map(x ->
{ Set<Set<UnifyPair>> z = new TypeUnify().unify(x, finiteClosure);
return z;
}
).collect(Menge::new, Menge::add, Menge::addAll);
//card gibt die Cardinalitaet der unifizierten Mengen an
Menge<Integer> card = vecunifyResult.stream().map(x -> x.size()).collect(Menge::new, Menge::add, Menge::addAll);
;//.reduce(1,(a,b) -> { if ((a > 0) && (b > 0)) return (a * b); else return 1; });
//Schritt 5: Bildung des cartesischen Produkts
//sollte wieder entfernt werden: Weiterarbeit mit:
//[[x_1 -> t_1, x_2 -> t2], [x_1 -> t'_1, x_2 -> t'_2]] x ... x [[x_n -> t_1n], [x_n -> t2n], [x_n -> t3n]]
Set<Set<UnifyPair>> cardprodret_start = new Menge<>();
cardprodret_start.add(new Menge<UnifyPair>());
//cart. Produkt mit Linkverschiebung
Set<Set<UnifyPair>> unifyResult = vecunifyResult.stream().reduce(cardprodret_start, (x, y) -> {
Set<Set<UnifyPair>> cardprodret= new Menge<>();
if (y.size() > 0) {
//System.out.println(y);
//Menge<Menge<Pair>> cardprodretold = x;
//cardprodret = new Menge<>();
for(Set<UnifyPair> xElement : x) {
for (Set<UnifyPair> yElement : y){
Set<UnifyPair> help = new Menge<>();
help.addAll(yElement);
help.addAll(xElement);
cardprodret.add(help);
}
}
}
else
return new Menge<>(); //kein unifiziertes Ergebnis, damit wird das Geseamtergebnis []
return cardprodret;
});
return unifyResult;
}
/////////////////////////////////////////////////////////////////////////
// TypeReconstructionAlgorithmus
/////////////////////////////////////////////////////////////////////////
/**
* Tyrekonstruktionsalgorithmus: ruft ¯Â¿Â½r jede Klasse den Algorithmus TRProg auf.
* Dessen Ergebnismenge A, die Menge aller Typannahmen, ¯Â¿Â½r eine Klasse dient als
* Eingabe ¯Â¿Â½r TRProg der ¯Â¿Â½chsten Klasse. Am Ende enth�lt A alle ¯Â¿Â½glichen
* Typkombinationen ¯Â¿Â½r alle Klassen zusammen.
* <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @return Liste aller ¯Â¿Â½glichen Typkombinationen
* @throws CTypeReconstructionException Wenn was schief ¯Â¿Â½uft
*/
public Menge<TypeinferenceResultSet> typeReconstruction(TypeAssumptions globalAssumptions)
{
Menge<TypeinferenceResultSet> ret = new Menge<TypeinferenceResultSet>();
//Logger initialisieren:
Logger typinferenzLog = Logger.getLogger("Typeinference");
//Alle Assumptions ¼r diese SourceFile sammeln:
for(Class klasse : this.KlassenVektor){
globalAssumptions.add(klasse.getPublicFieldAssumptions());
}
//Assumptions der importierten Klassen sammeln:
TypeAssumptions importAssumptions = this.makeBasicAssumptionsFromJRE(imports, true);
globalAssumptions.add(importAssumptions);
typinferenzLog.debug("Von JRE erstellte Assumptions: "+importAssumptions, Section.TYPEINFERENCE);
ConstraintsSet oderConstraints = new ConstraintsSet();
//Alle Constraints der in dieser SourceFile enthaltenen Klassen sammeln:
for(Class klasse : KlassenVektor){
oderConstraints.add(klasse.typeReconstruction(globalAssumptions));
}
/*////////////////
* Paare in MPairs umwandeln
* (Wird zunächst mal weggelassen. Constraints werden erst beim Unifizieren umgewandelt
*/////////////////
//UnifyTypeFactory.convert(oderConstraints);
//FiniteClosure generieren:
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(globalAssumptions);
typinferenzLog.debug("FiniteClosure: \n"+finiteClosure, Section.TYPEINFERENCE);
////////////////
//Typen in UnifyTypen umwandeln:
////////////////
UnifyConstraintsSet unifyConstraints = UnifyTypeFactory.convert(oderConstraints);
//UnmÃgliche ConstraintsSets aussortieren durch Unifizierung
Unifikationsalgorithmus unifier = (pairs)->new TypeUnify().unify(pairs, finiteClosure);
unifyConstraints.filterWrongConstraints(unifier);
//unifyConstraints.unifyUndConstraints(unifier); //rausgeworfen für Tests (08.12.2015)
typinferenzLog.debug("Übriggebliebene Konstraints:\n"+oderConstraints+"\n", Section.TYPEINFERENCE);
typinferenzLog.debug("Übriggebliebene Konvertierte Konstraints:\n"+unifyConstraints+"\n", Section.TYPEINFERENCE);
////////////////
//Karthesisches Produkt bilden:
////////////////
Set<Set<UnifyPair>> xConstraints = unifyConstraints.cartesianProduct();
//Sets zu Listen umwandeln:
//Set<List<UnifyPair>> allUnifiedConstraints = xConstraints.stream().map((set)-> new ArrayList<>(set)).collect(Menge::new, Menge::add, Menge::addAll);;
typinferenzLog.debug("Finite Closure: "+finiteClosure, Section.TYPEINFERENCE);
typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints, Section.TYPEINFERENCE);
//finiteClosure.generateFullyNamedTypes(globalAssumptions);
//////////////////////////////
// Unifizierung der Constraints:
//////////////////////////////
boolean unifyFail = true;
for(Set<UnifyPair> constraints : xConstraints){
//Alle durch das Karthesische Produkt entstandenen glichkeiten durchgehen:
typinferenzLog.debug("\nUnifiziere Constraints:\n"+constraints, Section.TYPEINFERENCE);
typinferenzLog.debug("\nFC:\n"+finiteClosure, Section.TYPEINFERENCE);
long start = System.currentTimeMillis();
Set<Set<UnifyPair>> unifyResult = new TypeUnify().unify(constraints, finiteClosure);
long time = System.currentTimeMillis()-start;
typinferenzLog.debug("\nErgebnis der Unifizierung:\n"+unifyResult, Section.TYPEINFERENCE);
typinferenzLog.debug("\nAnzahl Lösungen:\n"+unifyResult.size(), Section.TYPEINFERENCE);
//typinferenzLog.debug("\nZeit für Unifizierung: "+time + "ms", Section.TYPEINFERENCE);
Menge<Menge<Pair>> convertedResult = unifyResult.parallelStream().<Menge<Pair>>map((Set<UnifyPair> resultSet)->{
Menge<Pair> innerConvert = resultSet.stream().map((UnifyPair mp)->UnifyTypeFactory.convert(mp))
.collect(Menge<Pair>::new, Menge::add, Menge::addAll);
return innerConvert;
}).collect(Menge::new, Menge::add, Menge::addAll);
Menge<Pair> convertedConstraints = constraints.stream().map(
(UnifyPair mp)->{return UnifyTypeFactory.convert(mp);}
).collect(Menge<Pair>::new, Menge::add, Menge::addAll);
//Dann den Ergebnissen anfügen
typinferenzLog.debug("\nErgebnis der Unifizierung (Konvertiert):\n"+convertedResult, Section.TYPEINFERENCE);
//result.addAll(convertedResult);
typinferenzLog.debug("\nJavaFiles:\n", Section.TYPEINFERENCE);
//typinferenzLog.debug(this.printJavaCode(new ResultSet(new Menge<Pair>())));
//¼r jede Klasse in diesem SourceFile gilt das selbe ResultSet:
for(Class klasse : this.KlassenVektor){
//Der Unifikationsalgorithmus kann wiederum auch mehrere sungen errechnen, diese werden im folgenden durchlaufen:
for(Menge<Pair> resultSet : convertedResult){
unifyFail = false; //Ein Unifiziertes Ergebnis ist entstanden (es kann auch leer sein, das bedeutet nur, dass die Constraints mindestens in einem Fall Sinn ergaben)
//Add Result set as a new ReconstructionResult to ret:
TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet(klasse, convertedConstraints, new ResultSet(resultSet));
ret.add(reconstructionResult);
//ResultSet res = new ResultSet(resultSet);
typinferenzLog.debug("JavaFile für ResultSet "+reconstructionResult+"\n", Section.TYPEINFERENCE);
typinferenzLog.debug(klasse.printJavaCode(reconstructionResult), Section.TYPEINFERENCE);
}
}
}
if(unifyFail){
if(!this.KlassenVektor.isEmpty())throw new TypeinferenceException("Fehler in Typinferierung", this.KlassenVektor.firstElement());
}
return ret;
}
/**
* Erstellt die Assumptions der standardmäßig importierten Packages (java.lang.) sowie der von imports übergebenen Klassen zusammen.
* @param imports
* @param withSuptypes - Gibt an, ob auch die subklassen der Packages den Assumptions angefügt werden sollen.
* @return
* TODO: Diese Methode neu erstellen
*/
public TypeAssumptions makeBasicAssumptionsFromJRE(List<JavaClassName> imports, boolean withSubtypes)
// ino.end
// ino.method.makeBasicAssumptionsFromJRE.21409.body
{
return null;
}
// ino.end
private Class getSuperClassOfJREClass(java.lang.Class<?> x, TypeAssumptions ass) {
Class ret;
java.lang.Class s = x.getSuperclass();
if(s == null){
return new Class("java.lang.Object",new Modifiers(), 0);
}
Menge<String> supertypeGenPara = new Menge<>();//Die Generischen Parameter ¼r die Superklasse berechnen:
java.lang.reflect.TypeVariable[] superclassTVS=s.getTypeParameters();
for(int tvi=0;tvi<superclassTVS.length;tvi++){
supertypeGenPara.addElement(superclassTVS[tvi].getName());
}
Class ss = this.getSuperClassOfJREClass(s, ass);
ret = new Class(s.getName(),ss.getType(),new Modifiers(),supertypeGenPara);
ass.addClassAssumption(new ClassAssumption(ss)); //Die beiden SuperKlassen den Assumptions anfügen...
ass.addClassAssumption(new ClassAssumption(ret));
return ret;
}
// ino.method.isBaseType.21412.definition
private boolean isBaseType(String type)
// ino.end
// ino.method.isBaseType.21412.body
{
return baseTypeTranslationTable.containsValue(type);
}
// ino.end
/*Die contains Methode des Menges vergleicht bei Strings nicht korrekt,
* da zwei Strings mit dem gleichen Inhalt unterschiedliche Instanzen sind.
* Deshalb diese Methode 07-01-20 luar*/
private boolean containsString(Menge<UsedId> searchMenge, String searchString)
{
boolean found = false;
for(UsedId id : searchMenge)
{
String s = id.getQualifiedName().toString();
found |= s.equals(searchString);
}
return found;
}
// ino.method.createTypeFromJavaGenericType.21415.definition
private Type createTypeFromJavaGenericType(java.lang.reflect.Type type, java.lang.Class<?> cl, Hashtable<String,GenericTypeVar>jreSpiderRegistry, Class parentClass)
// ino.end
// ino.method.createTypeFromJavaGenericType.21415.body
{
/* auskommentiert, da die Klassen von Sun in der Open JDK 1.8 nicht unterstützt werden.
if(type instanceof TypeVariableImpl){
TypeVariableImpl tvi=((TypeVariableImpl)type);
return(new GenericTypeVar(jreSpiderRegistry.get(tvi.getName()).getName().toString(),parentClass,-1));
}else{
*/
GenericTypeVar gtv = jreSpiderRegistry.get(type.getTypeName());
if(gtv != null)return gtv;
//new GenericTypeVar(jreSpiderRegistry.get(type.getTypeName()).getName().toString(),parentClass,-1));
//String jccNameForClass=baseTypeTranslationTable.get(cl.getSimpleName());
String jccNameForClass=baseTypeTranslationTable.get(cl.getName());
if(cl.getSimpleName().equalsIgnoreCase("void")){
return(new Void(parentClass,-1));
}else if(jccNameForClass!=null){
RefType rt=new RefType(jccNameForClass,parentClass,-1);
rt.setPrimitiveFlag(true);
return(rt);
}else{
//return(new RefType(cl.getSimpleName()));
return(new RefType(cl.getName(),parentClass,-1));
}
//}
}
// ino.method.getPackageName.21427.defdescription type=javadoc
/**
* Erzeugt ¯Â¿Â½r jede Klasse einen Menge, in den Referenzen auf die GenericTypeVars
* dieser Klasse gespeichert werden. Diese Mengeen werden unter den Klassennamen
* in der
* Ergebnisdatenstruktur abgelegt. Au�erdem werden alle Klassennamen gespeichert.
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param res
* /
* /*private void addClassNamesAndGenericsToRR(CTypeReconstructionResult res){
* Iterator<Class> it = this.getClassIterator();
* while(it.hasNext()){
* Class cl = it.next();
* res.addClassName(cl.get_classname());
* Menge<GenericTypeVar> genericsList = new Menge<GenericTypeVar>();
*
* for(int i =0; i<cl.get_ParaList().size(); i++){
* Type para = (Type)cl.get_ParaList().elementAt(i);
* if(para instanceof GenericTypeVar){
* genericsList.addElement((GenericTypeVar)para);
* }
* }
* res.addGenericTypeVars(cl.get_classname(), genericsList);
* }
* }
*/
// ino.end
// ino.method.getPackageName.21427.definition
public UsedId getPackageName()
// ino.end
// ino.method.getPackageName.21427.body
{
return pkgName;
}
// ino.end
// ino.method.setPackageName.21430.definition
public void setPackageName(UsedId pkgName)
// ino.end
// ino.method.setPackageName.21430.body
{
this.pkgName = pkgName;
// Die Package-Namen fuer alle Klassen und Interfaces
// im Source-File nachziehen
for (int i=0; i<KlassenVektor.size(); i++) {
KlassenVektor.elementAt(i).setPackageName(pkgName);
}
}
// ino.end
public ImportDeclarations getImports()
{
return(imports);
}
// ino.method.getClassIterator.21439.definition
public Iterator<Class> getClassIterator()
// ino.end
// ino.method.getClassIterator.21439.body
{
return KlassenVektor.iterator();
}
// ino.end
// ino.method.getInterfaceIterator.21442.definition
public Iterator<Interface> getInterfaceIterator()
// ino.end
// ino.method.getInterfaceIterator.21442.body
{
return InterfaceVektor.iterator();
}
// ino.end
@Override
public void parserPostProcessing(SyntaxTreeNode parent) {
if(parent!=null)throw new DebugException("Eine SourceFile hat kein Elternelement im Syntaxbaum");
super.parserPostProcessing(this);
//for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this);
}
@Override
public SyntaxTreeNode getParent() {
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
for(Class cl : this.KlassenVektor){
ret.add(cl);
}
return ret;
}
/**
* SourceFile stellt eine geparste Java-Datei dar. Mit dieser Methode wird der Name der eingelesenen Datei gesetzt.
* @param filename - Der Name der eingelesenen JavaDatei
*/
@Deprecated
public void setFileName(String filename) {
//this.filename = filename;
}
@Override
public int getOffset() {
// TODO Auto-generated method stub
return 0;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
throw new NotImplementedException();
}
@Override
public int getVariableLength() {
// TODO Auto-generated method stub
return 0;
}
/**
* Bytecode generieren für das resultSet
* @return
*/
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResults results) {
Menge<ByteCodeResult> ret = new Menge<>();
for(Class cl : this.KlassenVektor){
ret.add(cl.genByteCode(results));
}
//Alle FunN Klassen erzeugen:
for(ClassAssumption funNAss : MyCompiler.makeFunNAssumptions().getClassAssumptions()){
ret.add(funNAss.getAssumedClass().genByteCode(results));
}
/*
//Add all FunN Interfaces
for(Pair ucons : results.getUnifiedConstraints()){
for(Type t : ucons.getTypes()){
List<Class> xClasses = t.isClassFromJavaX();
for(Class xClass : xClasses){
ByteCodeResult bC = xClass.genByteCode(results);
if(! ret.contains(bC))ret.add(bC);
}
}
}
*/
return ret;
}
} }
// ino.end // ino.end

View File

@ -2,8 +2,136 @@ package de.dhbwstuttgart.syntaxtree;
import java.util.List; import java.util.List;
import org.apache.bcel.generic.ClassGen;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.GenericTypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public abstract class SyntaxTreeNode implements IItemWithOffset{ public abstract class SyntaxTreeNode implements IItemWithOffset{
protected SyntaxTreeNode parent;
protected int offset;
public SyntaxTreeNode(int offset){
this.offset = offset;
}
/**
* Wird nach dem Parsen aufgerufen.
* Erfüllt folgenden Aufgaben:
* 1. ¼llt fehlende Typangaben mit TPHs auf.
* 2. Verknüpft die Knoten des Syntaxbaums. (setzt Parent)
* 3. Wechselt RefTypes gegebenenfalls mit GenericTypeVars aus.
* 4. ¼hrt einen Teil des Syntaxckecks durch.
*
*/
public void parserPostProcessing(SyntaxTreeNode parent) {
if(parent == null)throw new NullPointerException();
this.parent = parent;
for(SyntaxTreeNode node : this.getChildren())
if(node!=null)node.parserPostProcessing(this);
}
public SyntaxTreeNode getParent() {
//if(this.parent == null)throw new NullPointerException();
return this.parent;
}
public abstract List<? extends SyntaxTreeNode> getChildren();
/**
* Eine Beschreibung/Name des SyntaxTree-Nodes
* Hat nichts mit der Description im Bytecode zu tun,
* wird für die Anzeige des AST im Plugin verwendet
* @return
*/
public String getDescription(){
return this.toString();
}
@Override
public boolean equals(Object object){
if(!(object instanceof SyntaxTreeNode))return false;
SyntaxTreeNode equal = (SyntaxTreeNode)object;
if(!equal.getDescription().equals(this.getDescription()))return false;
if(this.getParent()!=null)
if(!this.getParent().equals(equal.getParent()))return false; //auch das Elternelement überprüfen.
return true;
}
/**
* Methode zur Generierung der TypeInsertPoints
* @param insertSet - Generierte InsertPoints werden dem insertSet angefügt
* @param result - Das ResultSet auf dessen Basis die InsertPoints generiert werden
*/
public void addTypeInsertPoints(TypeInsertSet insertSet,ResultSet result) {
for(SyntaxTreeNode node : this.getChildren()){
node.addTypeInsertPoints(insertSet, result);
}
TypeInsertPoint tip = null; //Der TypInsertPoint ¼r diesen Knoten
//Fall der Knoten ein TypeInsertable ist, kann direkt der TypeInsertPoint generiert werden.
if(this instanceof TypeInsertable){
TypeInsertable that = (TypeInsertable)this;
Type t = that.getType();
if(t instanceof TypePlaceholder){
tip = that.createTypeInsertPoint((TypePlaceholder) t, result);
insertSet.add(tip);//ret.addAll(((TypePlaceholder)t).getTypeInsertPoints(result));
}
/*
//¼r den Fall, dass dieser Knoten Generische Variablen halten kann.
if(that instanceof Generic && that.getOffset()>=0){
//Alle unresolvedTPHs ermitteln und GenericTypeVarInsertPoints bilden:
Menge<TypePlaceholder> uTPHs = insertSet.getUnresolvedTPHs();
if(uTPHs.size()>0){//Nur wenn es auch unresolvedTPHs gibt:
Menge<Pair> gPairs = result.getConstraintsFor(uTPHs);
if(gPairs.size()>0){
GenericTypeInsertPoint genericTIP = new GenericTypeInsertPoint(that,gPairs,result);
insertSet.add(genericTIP);
}
}
}
*/
}
}
public SyntaxTreeNode getMatchingParentNode(SyntaxTreeNode inNode) {
SyntaxTreeNode node = inNode;
while(node!=null){
if(node.equals(this))return this;
node = inNode.getParent();
}
if(this.getParent()!=null)return this.getParent().getMatchingParentNode(inNode);
return null;
}
public GTVDeclarationContext getGTVDeclarationContext(){
if(this.getParent()==null)
throw new NullPointerException();//throw new DebugException("getGTVDeclarationContext auf unzulässiger Klasse aufgerufen");
return this.getParent().getGTVDeclarationContext();
}
public int getOffset(){
return offset;
}
public abstract JavaCodeResult printJavaCode(ResultSet resultSet);
} }

View File

@ -0,0 +1,189 @@
package de.dhbwstuttgart.syntaxtree.factory;
import java.lang.reflect.Parameter;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.typecheck.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.modifier.Public;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.Menge;
public class ASTFactory {
private final JavaClassRegistry names;
/**
* 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.
*/
//private JavaClassRegistry names;
public ASTFactory(JavaClassRegistry scope){
names = scope;
}
public static Method createEmptyMethod(String withSignature, Class parent) {
return ASTFactory.createMethod(withSignature, new ParameterList(), new Block(), parent);
}
public static 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("<init>", 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<String> 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);
}
/**
*
* @param jreClass
* @return
*/
public Class createClass(java.lang.Class jreClass){
JavaClassName name = names.getName(jreClass.getName());
List<Method> methoden = new ArrayList<>();
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
}
for(java.lang.reflect.Method method : jreClass.getMethods()){
methoden.add(createMethod(method, jreClass));
}
List<Field> felder = new ArrayList<>();
Modifiers modifier = new Modifiers();
modifier.addModifier(new Public());
boolean isInterface = jreClass.isInterface();
java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass = null;
if(superjreClass != null){
superClass = createType(superjreClass);
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
superClass = createType(java.lang.Object.class);
}
List<RefType> implementedInterfaces = new ArrayList<>();
for(java.lang.Class jreInterface : jreClass.getInterfaces()){
implementedInterfaces.add(createType(jreInterface));
}
int offset = 0; //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
return new Class(name, methoden, felder, modifier, isInterface, superClass, implementedInterfaces, offset);
}
/**
* Wandelt eine Methode aus der JRE in eine Methode für unseren AST um.
* @param jreMethod
* @param inClass
* @return
*/
public Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName();
RefType returnType = createType(jreMethod.getReturnType());
Parameter[] jreParams = jreMethod.getParameters();
List<FormalParameter> params = new ArrayList<>();
for(Parameter jreParam : jreParams){
RefType paramType = createType(jreParam.getType());
params.add(new FormalParameter(jreParam.getName(),paramType,-1));
}
ParameterList parameterList = new ParameterList(params);
Block block = new Block(new ArrayList<Statement>(), -1);
List<GenericTypeVar> gtvs = new ArrayList<>();
for(TypeVariable jreTV : jreMethod.getTypeParameters()){
GenericTypeVar gtv = createGeneric(jreTV, inClass);
gtvs.add(gtv);
}
GenericDeclarationList gtvDeclarations = new GenericDeclarationList(gtvs,-1);
int offset = -1;
return new Method(name, returnType, parameterList, block, gtvDeclarations, offset);
}
public RefType createType(java.lang.Class jreClass){
List<RefType> params = new ArrayList<>();
for(TypeVariable jreTV : jreClass.getTypeParameters()){
RefType gtv = createType(jreTV);
params.add(gtv);
}
jreClass
return new RefType(jreClass.getName(), params, -1);
}
public RefType createType(java.lang.reflect.Type type){
RefType ret = new RefType(type.getTypeName(), -1);
//TODO hier die Generischen Variablen extrahieren
return ret;
}
/**
* Erstellt eine GenericTypeVar oder eine BoundedGenericTypeVar
* Um die Variablen korrekt zu generieren, muss die Klasse inClass übergeben werden, in der dieser Generic auftaucht
* TODO: Warum?
* Wird der AST von JREClass erzeugt, so kann davon ausgegangen werden, dass die Generics korrekt sind.
* Unser AST ist immutable und nicht im Kreis verzeigert. Generics die gleich heißen und gleiche Bounds haben, sind auch gleich. Müssen nicht die selben Instanzen sein.
* @param jreTypeVar
* @param inClass Die Klasse in der der Typ auftritt
* @return
*/
public GenericTypeVar createGeneric(TypeVariable jreTypeVar, java.lang.Class inClass){
//TODO: Bei den Namen der Parameter des Generishen Typs nachschauen, ob er in der Klasse als Generic deklariert wurde
String name = jreTypeVar.getTypeName();
List<RefType> genericBounds = new ArrayList<>();
java.lang.reflect.Type[] bounds = jreTypeVar.getBounds();
if(bounds.length > 0){
for(java.lang.reflect.Type bound : bounds){
genericBounds.add(createType(bound));
}
return new BoundedGenericVar();
}
return new GenericTypeVar();
}
public static Class createInterface(String className, RefType superClass, Modifiers modifiers,
Menge supertypeGenPara, SourceFile parent){
Class generatedClass = new Class(new JavaClassName(className), new ArrayList<Method>(), new ArrayList<Field>(), modifiers,
true, superClass, new ArrayList<RefType>(), new GenericDeclarationList(), -1);
generatedClass.parserPostProcessing(parent);
return generatedClass;
}
public static Class createObjectClass() {
Class generatedClass = new Class("java.lang.Object", 0);
return generatedClass;
}
public static RefType createObjectType(){
return createObjectClass().getType();
}
}

View File

@ -0,0 +1,81 @@
package de.dhbwstuttgart.syntaxtree.factory;
public class NameGenerator {
private static String strNextName = "A";
/**
* Berechnet einen neuen, eindeutigen Namen ¯Â¿Â½r eine neue
* <code>TypePlaceholder</code>. <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @return Der Name
*/
public static String makeNewName()
{
// otth: Funktion berechnet einen neuen Namen anhand eines alten gespeicherten
String strReturn = strNextName;
// ¯Â¿Â½chster Name berechnen und in strNextName speichern
inc( strNextName.length() - 1 );
return strReturn;
}
/**
* Hilfsfunktion zur Berechnung eines neuen Namens
* <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param i
*/
private static void inc(int i)
{
// otth: Hilfsfunktion zur Berechnung eines neuen Namens
// otth: Erh�hung des Buchstabens an der Stelle i im String strNextName
// otth: Nach �berlauf: rekursiver Aufruf
// falls i = -1 --> neuer Buchstabe vorne anf�gen
if ( i == -1 )
{
strNextName = "A" + strNextName;
return;
}
char cBuchstabe = (char)(strNextName.charAt( i ));
cBuchstabe++;
if ( cBuchstabe - 65 > 25 )
{
// aktuelle Stelle: auf A zuruecksetzen
manipulate( i, 'A' );
// vorherige Stelle erh�hen
inc( i - 1 );
}
else
{
// aktueller Buchstabe �ndern
manipulate( i, cBuchstabe );
}
}
/**
* Hilfsfunktion zur Berechnung eines neuen Namens.
* <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @param nStelle
* @param nWert
*/
private static void manipulate( int nStelle, char nWert )
{
// otth: Hilfsfunktion zur Berechnung eines neuen Namens
// otth: Ersetzt im String 'strNextName' an der Position 'nStelle' den Buchstaben durch 'nWert'
String strTemp = "";
for( int i = 0; i < strNextName.length(); i++)
{
if ( i == nStelle )
strTemp = strTemp + nWert;
else
strTemp = strTemp + strNextName.charAt( i );
}
strNextName = strTemp;
}
}

View File

@ -0,0 +1,9 @@
package de.dhbwstuttgart.syntaxtree.factory;
/**
* Generiert Hilfsmethoden für die Unary und Binary Operatoren
* Diese Methoden stellen die möglichen Operationen +,-,++, etc dar
*/
public class PrimitiveMethodsGenerator {
}

View File

@ -0,0 +1,39 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
public class UnifyPairMengenBuilder {
private Menge<Pair> buildMenge = new Menge<Pair>();
public void addPair(Type t1, Type t2) {
buildMenge.add(new Pair(t1, t2));
}
public void addPair(Type t1, Type t2, PairOperator pairOp) {
buildMenge.add(new Pair(t1, t2, pairOp));
}
public Menge<Pair> getPairMenge() {
return buildMenge;
}
public Menge<Menge<Pair>> getNestedPairMenge() {
Menge<Menge<Pair>> nested = new Menge<>();
for(Pair p : buildMenge) {
Menge<Pair> m = new Menge<Pair>();
m.add(p);
nested.add(m);
}
return nested;
}
public void clear() {
buildMenge = new Menge<Pair>();
}
}

View File

@ -0,0 +1,217 @@
package de.dhbwstuttgart.syntaxtree.factory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.EinzelElement;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.UnifyConstraintsSet;
import de.dhbwstuttgart.typeinference.UnifyOderConstraint;
import de.dhbwstuttgart.typeinference.UnifyUndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class UnifyTypeFactory {
private final static NullSyntaxTreeNode NULL_NODE = new NullSyntaxTreeNode();
public static FiniteClosure generateFC(TypeAssumptions fromAss){
HashSet<UnifyPair> pairs = new HashSet<>();
for(ClassAssumption cAss : fromAss.getClassAssumptions()){
UnifyType tl = UnifyTypeFactory.convert(cAss.getAssumedClass().getType().TYPE(fromAss, cAss.getAssumedClass()));
Type superClass = cAss.getAssumedClass().getSuperClass();
if(superClass != null){
UnifyType tr = UnifyTypeFactory.convert(superClass.TYPE(fromAss, cAss.getAssumedClass()));
pairs.add(generateSmallerPair(tl, tr));
}
}
return new FiniteClosure(pairs);
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLER);
}
public static UnifyPair generateSmallerDotPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLERDOT);
}
public static UnifyType convert(Type t){
//Es wurde versucht ein Typ umzuwandeln, welcher noch nicht von der Factory abgedeckt ist
if(t instanceof GenericTypeVar){
return UnifyTypeFactory.convert((GenericTypeVar)t);
}else if(t instanceof FunN){
return UnifyTypeFactory.convert((FunN)t);
}else if(t instanceof TypePlaceholder){
return UnifyTypeFactory.convert((TypePlaceholder)t);
}else if(t instanceof ExtendsWildcardType){
return UnifyTypeFactory.convert((ExtendsWildcardType)t);
}else if(t instanceof SuperWildcardType){
return UnifyTypeFactory.convert((SuperWildcardType)t);
}else if(t instanceof RefType){
return UnifyTypeFactory.convert((RefType)t);
}
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
}
public static UnifyType convert(RefType t){
UnifyType ret;
if(t.getParaList() != null && t.getParaList().size() > 0){
Menge<UnifyType> params = new Menge<>();
for(Type pT : t.getParaList()){
params.add(UnifyTypeFactory.convert(pT));
}
ret = new ReferenceType(t.get_Name(),new TypeParams(params));
}else{
ret = new ReferenceType(t.get_Name());
}
return ret;
}
public static UnifyType convert(FunN t){
UnifyType ret;
Menge<UnifyType> params = new Menge<>();
if(t.getParaList() != null && t.getParaList().size() > 0){
for(Type pT : t.getParaList()){
params.add(UnifyTypeFactory.convert(pT));
}
}
ret = FunNType.getFunNType(new TypeParams(params));
return ret;
}
public static UnifyType convert(TypePlaceholder tph){
return new PlaceholderType(tph.get_Name());
}
public static UnifyType convert(ExtendsWildcardType t){
return new ExtendsType(UnifyTypeFactory.convert(t.get_ExtendsType()));
}
public static UnifyType convert(SuperWildcardType t){
return new SuperType(UnifyTypeFactory.convert(t.get_SuperType()));
}
public static UnifyType convert(GenericTypeVar t){
return new PlaceholderType(TypePlaceholder.fresh(NULL_NODE).get_Name());
//return new ReferenceType(t.get_Name());
}
public static UnifyConstraintsSet convert(ConstraintsSet constraints) {
UnifyConstraintsSet ret = new UnifyConstraintsSet();
for(OderConstraint oC : constraints.getOderConstraints()){
ret.add(UnifyTypeFactory.convert(oC));
}
return ret;
}
public static UnifyOderConstraint convert(OderConstraint set) {
UnifyOderConstraint ret = new UnifyOderConstraint();
for(UndConstraint oC : set.getUndConstraints()){
ret.addConstraint(UnifyTypeFactory.convert(oC));
}
return ret;
}
public static UnifyUndConstraint convert(UndConstraint set) {
UnifyUndConstraint ret = new UnifyUndConstraint();
for(EinzelElement<Pair> oC : set.getPairs()){
ret.add(UnifyTypeFactory.convert(oC));
}
return ret;
}
public static UnifyPair convert(EinzelElement<Pair> p) {
return convert(p.getItem());
}
public static UnifyPair convert(Pair p) {
if(!p.OperatorSmaller())throw new NotImplementedException();
UnifyPair ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1)
, UnifyTypeFactory.convert(p.TA2));
return ret;
}
public static Pair convert(UnifyPair mp) {
Type tl = UnifyTypeFactory.convert(mp.getLhsType());
Type tr = UnifyTypeFactory.convert(mp.getRhsType());
return new Pair(tl, tr, mp.getPairOp());
}
public static Type convert(ReferenceType t) {
//TODO: Hier kann man die GTVs extrahieren
if(t.getName().toString().equals(Void.VOID_NAME))return new Void( 0);
RefType ret = new RefType(t.getName(),0);
ret.set_ParaList(convert(t.getTypeParams()));
return ret;
}
public static Type convert(FunNType t) {
RefType ret = new RefType(t.getName(),0);
ret.set_ParaList(convert(t.getTypeParams()));
return ret;
}
public static Type convert(SuperType t) {
RefType innerType = new RefType(t.getSuperedType().getName(),0);
return new SuperWildcardType(innerType);
}
public static Type convert(ExtendsType t) {
RefType innerType = new RefType(t.getExtendedType().getName(),0);
return new ExtendsWildcardType(innerType);
}
public static Type convert(PlaceholderType t) {
TypePlaceholder ret = TypePlaceholder.getInstance(t.getName());
if(ret == null){ //Dieser TPH wurde vom Unifikationsalgorithmus erstellt
ret = TypePlaceholder.fresh(t.getName(), NULL_NODE);
}
return ret;
}
public static Type convert(UnifyType t) {
if(t instanceof FunNType)return convert((FunNType) t);
if(t instanceof ReferenceType)return convert((ReferenceType) t);
if(t instanceof SuperType)return convert((SuperType) t);
if(t instanceof ExtendsType)return convert((ExtendsType) t);
if(t instanceof PlaceholderType)return convert((PlaceholderType) t);
throw new NotImplementedException("Der Typ "+t+" kann nicht umgewandelt werden");
}
private static List<Type> convert(TypeParams typeParams) {
List<Type> ret = new ArrayList<>();
for(UnifyType uT : typeParams){
Type toAdd = convert(uT);
ret.add(toAdd);
}
return ret;
}
}

View File

@ -0,0 +1,32 @@
package de.dhbwstuttgart.syntaxtree.factory;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
public class Unify_FC_TTO_Builder {
private Menge<Pair> fc = new Menge<Pair>();
private Menge<Class> classes = new Menge<Class>();
/*
public void AddInheritance(Type t1, Type t2) {
if(t1 instanceof RefType)
if(!classes.stream().anyMatch(x -> x.getName().equals(t1.getName())))
classes.add(new Class(t1.get_Name(), t1.getOffset()));
if(t2 instanceof RefType)
if(!classes.stream().anyMatch(x -> x.getName().equals(t2.getName())))
classes.add(new Class(t2.get_Name(), t2.getOffset()));
fc.add(new Pair(t1, t2));
}
*/
public void clear() {
fc = new Menge<Pair>();
classes = new Menge<Class>();
}
}

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
/** /**
* Stellt den Modifier Abstract dar. * Stellt den Modifier Abstract dar.
@ -13,5 +15,9 @@ public class Abstract extends Modifier
return 0x0400; return 0x0400;
} }
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("abstract");
}
} }

View File

@ -1,6 +1,10 @@
// ino.module.Final.8586.package // ino.module.Final.8586.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.class.Final.24022.description type=javadoc // ino.class.Final.24022.description type=javadoc
/** /**
* Stellt den Modifier Final dar. * Stellt den Modifier Final dar.
@ -22,5 +26,10 @@ public class Final extends Modifier
} }
// ino.end // ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("final");
}
} }
// ino.end // ino.end

View File

@ -3,6 +3,8 @@
*/ */
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
/** /**
* @author Daniel * @author Daniel
@ -14,5 +16,8 @@ public class InterfaceModifier extends Modifier {
return 0x0200; return 0x0200;
} }
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("interface");
}
} }

View File

@ -1,6 +1,8 @@
// ino.module.Modifier.8587.package // ino.module.Modifier.8587.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.end // ino.end
// ino.class.Modifier.24029.declaration // ino.class.Modifier.24029.declaration
@ -18,5 +20,6 @@ public abstract class Modifier
public abstract short getBitmask(); public abstract short getBitmask();
// ino.end // ino.end
public abstract JavaCodeResult printJavaCode(ResultSet resultSet);
} }
// ino.end // ino.end

View File

@ -2,21 +2,129 @@
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
// ino.end // ino.end
// ino.module.Modifiers.8588.import
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.end
// ino.class.Modifiers.24035.description type=javadoc // ino.class.Modifiers.24035.description type=javadoc
import java.util.ArrayList;
import java.util.List;
/** /**
* Die Klasse beinhaltet die Liste der Access-Modifier fuer eine Klasse, * Die Klasse beinhaltet die Liste der Access-Modifier fuer eine Klasse,
* Methode usw. * Methode usw.
*/ */
public class Modifiers public class Modifiers
{ {
protected List<Modifier> modifier = new ArrayList<Modifier>(); protected Menge<Modifier> modifier = new Menge<Modifier>();
// ino.end // ino.end
// ino.method.getModifiers.24041.definition
public Menge<Modifier> getModifiers()
// ino.end
// ino.method.getModifiers.24041.body
{
return this.modifier;
}
// ino.end
// ino.method.setModifier.24044.definition
public void setModifier(Menge<Modifier> modifier)
// ino.end
// ino.method.setModifier.24044.body
{
if (modifier != null) this.modifier = modifier;
}
// ino.end
// ino.method.addModifier.24047.defdescription type=javadoc
/**
* Fuegt den angegebenen Modifier zur Auflistung hinzu.
*/
// ino.end
// ino.method.addModifier.24047.definition
public void addModifier(Modifier mod)
// ino.end
// ino.method.addModifier.24047.body
{
modifier.addElement(mod);
}
// ino.end
// ino.method.includesModifier.24050.defdescription type=javadoc
/**
* Gibt zurueck, ob der angegebene Modifier enthalten ist.
*/
// ino.end
// ino.method.includesModifier.24050.definition
public boolean includesModifier(Modifier mod)
// ino.end
// ino.method.includesModifier.24050.body
{
String class1 = mod.getClass().toString();
String class2;
for (int i=0; i<modifier.size(); i++) {
// Anmerkung: Vergleich mit instanceof nicht moeglich
class2 = modifier.elementAt(i).getClass().toString();
if (class2.equals(class1)) return true;
}
return false;
}
// ino.end
// ino.method.ensureAbstract.24053.defdescription type=javadoc
/**
* Stellt sicher, dass ABSTRACT in der Modifierliste
* vorkommt. Wird u.a. bei Interfaces benoetigt.
*
*/
// ino.end
// ino.method.ensureAbstract.24053.definition
public void ensureAbstract()
// ino.end
// ino.method.ensureAbstract.24053.body
{
if (!includesModifier(new Abstract()))
modifier.addElement(new Abstract());
}
// ino.end
public void ensurePublic()
{
if (!includesModifier(new Public()))
modifier.addElement(new Public());
}
/**
* Gibt den Bitmaskenwert fuer die enthaltenen Access-Modifier
* zurueck.
*/
public short calculate_access_flags()
{
short ret = 0;
for (int i = 0; i < modifier.size(); i++) {
ret += modifier.elementAt(i).getBitmask();
}
// Falls nichts angegeben, auf Public setzen
if (ret == 0) {
Public p = new Public();
ret = p.getBitmask();
}
return ret;
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
for(Modifier mod : this.modifier){
ret.attach(mod.printJavaCode(resultSet)).attach( " ");
}
return ret;
}
} }
// ino.end // ino.end

View File

@ -1,6 +1,10 @@
// ino.module.Private.8589.package // ino.module.Private.8589.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.class.Private.24059.declaration // ino.class.Private.24059.declaration
public class Private extends Modifier public class Private extends Modifier
// ino.end // ino.end
@ -16,5 +20,10 @@ public class Private extends Modifier
} }
// ino.end // ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("private");
}
} }
// ino.end // ino.end

View File

@ -1,6 +1,9 @@
// ino.module.Protected.8590.package // ino.module.Protected.8590.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.class.Protected.24066.declaration // ino.class.Protected.24066.declaration
public class Protected extends Modifier public class Protected extends Modifier
@ -17,5 +20,10 @@ public class Protected extends Modifier
} }
// ino.end // ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("protected");
}
} }
// ino.end // ino.end

View File

@ -1,6 +1,10 @@
// ino.module.Public.8591.package // ino.module.Public.8591.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.class.Public.24073.declaration // ino.class.Public.24073.declaration
public class Public extends Modifier public class Public extends Modifier
// ino.end // ino.end
@ -16,5 +20,10 @@ public class Public extends Modifier
} }
// ino.end // ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("public");
}
} }
// ino.end // ino.end

View File

@ -1,6 +1,9 @@
// ino.module.Static.8592.package // ino.module.Static.8592.package
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
// ino.class.Static.24080.declaration // ino.class.Static.24080.declaration
public class Static extends Modifier public class Static extends Modifier
@ -17,5 +20,10 @@ public class Static extends Modifier
} }
// ino.end // ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("static");
}
} }
// ino.end // ino.end

View File

@ -3,6 +3,9 @@
*/ */
package de.dhbwstuttgart.syntaxtree.modifier; package de.dhbwstuttgart.syntaxtree.modifier;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
/** /**
* @author Daniel * @author Daniel
* *
@ -13,4 +16,8 @@ public class Super extends Modifier {
return 0x0020; return 0x0020;
} }
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("super");
}
} }

View File

@ -14,6 +14,27 @@ import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.InvokeInstruction; import org.apache.bcel.generic.InvokeInstruction;
import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
// ino.class.AddOp.24088.declaration // ino.class.AddOp.24088.declaration
@ -26,8 +47,115 @@ public abstract class AddOp extends Operator
// ino.end // ino.end
// ino.method.AddOp.24092.body // ino.method.AddOp.24092.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
protected Hashtable<RefType,RefType> getOperatorTypes() {
Hashtable<RefType, RefType> types = new Hashtable<RefType, RefType>();
types.put(new RefType("java.lang.Integer",this,-1),new RefType("java.lang.Integer",this,-1));
types.put(new RefType("java.lang.Double",this,-1),new RefType("java.lang.Double",this,-1));
types.put(new RefType("java.lang.Float",this,-1), new RefType("java.lang.Float",this,-1));
types.put(new RefType("java.lang.Long",this,-1), new RefType("java.lang.Long",this,-1));
types.put(new RefType("java.lang.String",this,-1), new RefType("java.lang.String",this,-1));
return types;
}
@Override
public HashMap<Type,Type> getReturnTypes(TypeAssumptions ass) {
HashMap<Type,Type> ret = new HashMap<Type,Type>();
ret.put(new RefType("java.lang.Integer",this,-1).TYPE(ass, this), new RefType("java.lang.Integer",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Double",this,-1).TYPE(ass, this), new RefType("java.lang.Double",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Float",this,-1).TYPE(ass, this), new RefType("java.lang.Float",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Long",this,-1).TYPE(ass, this), new RefType("java.lang.Long",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.String",this,-1).TYPE(ass, this), new RefType("java.lang.String",this,-1).TYPE(ass, this));
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
/*
0: aload_1
1: invokevirtual #2 // Method java/lang/Integer.intValue:()I
4: aload_1
5: invokevirtual #2 // Method java/lang/Integer.intValue:()I
8: iadd
9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
12: areturn
*/
String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2(), rs);
if(returnType.equals("java.lang.String")){
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
ObjectType objectType = new ObjectType("java.lang.StringBuilder");
InstructionList il = new InstructionList();
il.append(_factory.createNew("java.lang.StringBuilder"));
il.append(new DUP());
il.append(_cg.getInstructionFactory().createInvoke("java.lang.StringBuilder", "<init>", org.apache.bcel.generic.Type.VOID, new org.apache.bcel.generic.Type[] {}, Constants.INVOKESPECIAL));
il.append(operator.get_Expr1().genByteCode(_cg, rs));
il.append(_cg.getInstructionFactory().createInvoke("java.lang.StringBuilder", "append", objectType, new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.STRING}, Constants.INVOKEVIRTUAL));
il.append(operator.get_Expr2().genByteCode(_cg, rs));
il.append(_cg.getInstructionFactory().createInvoke("java.lang.StringBuilder", "append", objectType, new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.STRING}, Constants.INVOKEVIRTUAL));
il.append(_cg.getInstructionFactory().createInvoke("java.lang.StringBuilder", "toString", new ObjectType("java.lang.String"), new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
return il;
}else{
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType);
il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType));
il.append(getOperator(returnType));
il.append(convertValueToObject(_factory, returnType));
return il;
}
}
private String getReturnType(Expr expr1, Expr expr2, TypeinferenceResultSet rs) {
Type type = expr1.getType();
if(type instanceof TypePlaceholder){
Type tphType = rs.getTypeOfPlaceholder((TypePlaceholder) expr1.getType());
if(tphType instanceof ExtendsWildcardType){
return ((ExtendsWildcardType) tphType).get_ExtendsType().get_Name();
}else if(tphType instanceof SuperWildcardType){
return ((SuperWildcardType) tphType).get_SuperType().get_Name();
}else{
return tphType.getName().toString();
}
}else{
return type.get_Name();
}
}
abstract ArithmeticInstruction getOperator(String returnType);
private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) {
if(returnType.equals("java.lang.Integer")){
return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.INT}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Double")){
return _factory.createInvoke("java.lang.Double", "valueOf", new ObjectType("java.lang.Double"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.DOUBLE}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Float")){
return _factory.createInvoke("java.lang.Float", "valueOf", new ObjectType("java.lang.Float"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.FLOAT}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Long")){
return _factory.createInvoke("java.lang.Long", "valueOf", new ObjectType("java.lang.Long"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.LONG}, Constants.INVOKESTATIC);
}else{
throw new NotImplementedException();
}
}
} }
// ino.end // ino.end

View File

@ -1,9 +1,18 @@
// ino.module.AndOp.8595.package // ino.module.AndOp.8595.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Binary;
import org.apache.bcel.generic.InstructionList; import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
// ino.class.AndOp.24101.declaration // ino.class.AndOp.24101.declaration
public class AndOp extends LogOp public class AndOp extends LogOp
@ -18,9 +27,14 @@ public class AndOp extends LogOp
{ {
super(offset,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
// TODO Auto-generated method stub
return null;
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,9 @@
// ino.module.DivideOp.8596.package // ino.module.DivideOp.8596.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.DivideOp.8596.import // ino.module.DivideOp.8596.import
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import org.apache.bcel.generic.ArithmeticInstruction; import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.DADD; import org.apache.bcel.generic.DADD;
@ -30,6 +32,22 @@ public class DivideOp extends MulOp
// ino.end // ino.end
// ino.method.DivideOp.24112.body // ino.method.DivideOp.24112.body
{ {
super(offset,variableLength);
} }
// ino.end
ArithmeticInstruction getOperator(String returnType) {
if(returnType.equals("java.lang.Integer")){
return new IDIV();
}else if(returnType.equals("java.lang.Double")){
return new DDIV();
}else if(returnType.equals("java.lang.Float")){
return new FDIV();
}else if(returnType.equals("java.lang.Long")){
return new LDIV();
}else{
throw new NotImplementedException();
}
}
} }
// ino.end // ino.end

View File

@ -17,9 +17,14 @@ public class EqualOp extends RelOp
// ino.end // ino.end
// ino.method.EqualOp.24122.body // ino.method.EqualOp.24122.body
{ {
super(offset, variableLength);
} }
// ino.end // ino.end
@Override
BranchInstruction getOperator() {
return new IF_ICMPNE(null);
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,8 @@
// ino.module.GreaterEquOp.8598.package // ino.module.GreaterEquOp.8598.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.GreaterEquOp.8598.import // ino.module.GreaterEquOp.8598.import
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.IF_ICMPLT; import org.apache.bcel.generic.IF_ICMPLT;
@ -22,9 +23,14 @@ public class GreaterEquOp extends RelOp
// ino.end // ino.end
// ino.method.GreaterEquOp.24138.body // ino.method.GreaterEquOp.24138.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
BranchInstruction getOperator() {
return new IF_ICMPLT(null);
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,9 @@
// ino.module.GreaterOp.8599.package // ino.module.GreaterOp.8599.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.GreaterOp.8599.import // ino.module.GreaterOp.8599.import
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.IF_ICMPLE; import org.apache.bcel.generic.IF_ICMPLE;
import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Binary;
@ -20,8 +22,14 @@ public class GreaterOp extends RelOp
// ino.end // ino.end
// ino.method.GreaterOp.24151.body // ino.method.GreaterOp.24151.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
BranchInstruction getOperator() {
return new IF_ICMPLE(null);
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,8 @@
// ino.module.LessEquOp.8600.package // ino.module.LessEquOp.8600.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.LessEquOp.8600.import // ino.module.LessEquOp.8600.import
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.IF_ICMPGT; import org.apache.bcel.generic.IF_ICMPGT;
@ -21,9 +22,14 @@ public class LessEquOp extends RelOp
// ino.end // ino.end
// ino.method.LessEquOp.24164.body // ino.method.LessEquOp.24164.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
BranchInstruction getOperator() {
return new IF_ICMPGT(null);
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,8 @@
// ino.module.LessOp.8601.package // ino.module.LessOp.8601.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.LessOp.8601.import // ino.module.LessOp.8601.import
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.IF_ICMPGE; import org.apache.bcel.generic.IF_ICMPGE;
import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Binary;
@ -20,8 +21,14 @@ public class LessOp extends RelOp
// ino.end // ino.end
// ino.method.LessOp.24177.body // ino.method.LessOp.24177.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
BranchInstruction getOperator() {
return new IF_ICMPGE(null);
}
} }
// ino.end // ino.end

View File

@ -5,6 +5,20 @@ package de.dhbwstuttgart.syntaxtree.operator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.statement.NotExpr;
import de.dhbwstuttgart.syntaxtree.statement.Null;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
@ -19,8 +33,28 @@ public abstract class LogOp extends Operator
// ino.end // ino.end
// ino.method.LogOp.24190.body // ino.method.LogOp.24190.body
{ {
super(offset, variableLength);
} }
// ino.end // ino.end
@Override
protected Hashtable<RefType, RefType> getOperatorTypes() {
Hashtable<RefType, RefType> types = new Hashtable<RefType, RefType>();
types.put(new RefType("java.lang.Boolean",this,-1), new RefType("java.lang.Boolean",this,-1));
return types;
}
@Override
public HashMap<Type,Type> getReturnTypes(TypeAssumptions ass) {
HashMap<Type,Type> ret = new HashMap<>();
ret.put(new RefType("java.lang.Boolean",this,-1).TYPE(ass, this), new RefType("java.lang.Boolean",this,-1).TYPE(ass, this));
return ret;
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,15 @@
// ino.module.MinusOp.8603.package // ino.module.MinusOp.8603.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.MinusOp.8603.impor // ino.module.MinusOp.8603.import
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.IADD;
import org.apache.bcel.generic.ISUB;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
@ -18,5 +26,9 @@ public class MinusOp extends AddOp
super(offset,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
ArithmeticInstruction getOperator(String returnType) {
return new ISUB();
}
} }
// ino.end // ino.end

View File

@ -1,4 +1,5 @@
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.bcel.generic.ArithmeticInstruction; import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.IREM; import org.apache.bcel.generic.IREM;
@ -18,8 +19,14 @@ public class ModuloOp extends MulOp
// ino.end // ino.end
// ino.method.ModuloOp.24225.body // ino.method.ModuloOp.24225.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
@Override
ArithmeticInstruction getOperator(String returnType) {
return new IREM();
}
} }
// ino.end // ino.end

View File

@ -2,11 +2,123 @@
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module. // ino.module.MulOp.8605.import
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.InvokeInstruction;
import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
// ino.class.MulOp.24231.declaration // ino.class.MulOp.24231.declaration
public abstract class MulOp extends Operator public abstract class MulOp extends Operator
// ino.end // ino.end
// ino.class.MulOp.24231.body // ino.class.MulOp.24231.body
{ {
// ino.method.MulOp.24235.definition
public MulOp(int offset, int variableLength)
// ino.end
// ino.method.MulOp.24235.body
{
super(offset, variableLength);
}
// ino.end
@Override
protected Hashtable<RefType, RefType> getOperatorTypes() {
Hashtable<RefType, RefType> types = new Hashtable<RefType, RefType>();
return types;
}
@Override
public HashMap<Type,Type> getReturnTypes(TypeAssumptions ass) {
HashMap<Type,Type> ret = new HashMap<>();
ret.put(new RefType("java.lang.Integer",this,-1).TYPE(ass, this), new RefType("java.lang.Integer",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Double",this,-1).TYPE(ass, this), new RefType("java.lang.Double",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Float",this,-1).TYPE(ass, this), new RefType("java.lang.Float",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Long",this,-1).TYPE(ass, this), new RefType("java.lang.Long",this,-1).TYPE(ass, this));
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
// TODO Plus Operator ist bis jetzt nur für Integer implementiert
/*
0: aload_1
1: invokevirtual #2 // Method java/lang/Integer.intValue:()I
4: aload_1
5: invokevirtual #2 // Method java/lang/Integer.intValue:()I
8: imul
9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
12: areturn
*/
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2(), rs);
InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType);
il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType));
il.append(getOperator(returnType));
il.append(convertValueToObject(_factory, returnType));
return il;
}
private String getReturnType(Expr expr1, Expr expr2, TypeinferenceResultSet rs) {
Type type = expr1.getType();
if(type instanceof TypePlaceholder){
Type tphType = rs.getTypeOfPlaceholder((TypePlaceholder) expr1.getType());
if(tphType instanceof ExtendsWildcardType){
return ((ExtendsWildcardType) tphType).get_ExtendsType().get_Name();
}else if(tphType instanceof SuperWildcardType){
return ((SuperWildcardType) tphType).get_SuperType().get_Name();
}else{
return tphType.getName().toString();
}
}else{
return type.get_Name();
}
}
abstract ArithmeticInstruction getOperator(String returnType);
private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) {
if(returnType.equals("java.lang.Integer")){
return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.INT}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Double")){
return _factory.createInvoke("java.lang.Double", "valueOf", new ObjectType("java.lang.Double"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.DOUBLE}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Float")){
return _factory.createInvoke("java.lang.Float", "valueOf", new ObjectType("java.lang.Float"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.FLOAT}, Constants.INVOKESTATIC);
}else if(returnType.equals("java.lang.Long")){
return _factory.createInvoke("java.lang.Long", "valueOf", new ObjectType("java.lang.Long"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.LONG}, Constants.INVOKESTATIC);
}else{
throw new NotImplementedException();
}
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,18 @@
// ino.module.NotEqualOp.8606.package // ino.module.NotEqualOp.8606.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.Not // ino.module.NotEqualOp.8606.import
import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.statement.Null;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.IF_ACMPEQ;
// ino.class.NotEqualOp.24241.declaration // ino.class.NotEqualOp.24241.declaration
public class NotEqualOp extends RelOp public class NotEqualOp extends RelOp
@ -13,7 +24,14 @@ public class NotEqualOp extends RelOp
// ino.end // ino.end
// ino.method.NotEqualOp.24245.body // ino.method.NotEqualOp.24245.body
{ {
super(offset,variableLength);
} }
// ino.end
@Override
BranchInstruction getOperator() {
return new IF_ACMPEQ(null);
}
} }
// ino.end // ino.end

View File

@ -1,12 +1,105 @@
// ino.module.Operator.8607.package // ino.module.Operator.8607.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.Operator.8607.import
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.DADD;
import org.apache.bcel.generic.FADD;
import org.apache.bcel.generic.IADD;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LADD;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
public abstract class Operator extends SyntaxTreeNode public abstract class Operator extends SyntaxTreeNode
{ {
private int offset;
private int variableLength;
public Operator(int offset,int variableLength)
{
this.offset=offset;
this.variableLength=variableLength;
}
public int getOffset()
{
return offset;
}
public int getVariableLength()
{
return variableLength;
}
/**
* @author timo
* This is cool:
* we call the abstract parent to it him what operator-types he expects. the rest of the algorithm
* is implemented in this class because it's always the same...
* @see Design Pattern: Template Method
*/
protected abstract Hashtable<RefType, RefType> getOperatorTypes( );
/**
* Liefert eine HashMap der Form: HashMap<ResultType, InputType>
* @param ass
* @return
*/
public abstract HashMap<Type,Type> getReturnTypes(TypeAssumptions ass);
public abstract InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator);
@Override
public Menge<SyntaxTreeNode> getChildren() {
return new Menge<>();
}
protected InstructionList getInstructionListForOperand(ClassGenerator _cg, TypeinferenceResultSet rs, Expr operand, String returnType){
InstructionList il = new InstructionList();
il.append(operand.genByteCode(_cg, rs));
if(returnType.equals("java.lang.Integer")){
il.append(_cg.getInstructionFactory().createInvoke("java.lang.Integer", "intValue", org.apache.bcel.generic.Type.INT, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
}else if(returnType.equals("java.lang.Double")){
il.append(_cg.getInstructionFactory().createInvoke("java.lang.Double", "doubleValue", org.apache.bcel.generic.Type.DOUBLE, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
}else if(returnType.equals("java.lang.Float")){
il.append(_cg.getInstructionFactory().createInvoke("java.lang.Float", "floatValue", org.apache.bcel.generic.Type.FLOAT, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
}else if(returnType.equals("java.lang.Long")){
il.append(_cg.getInstructionFactory().createInvoke("java.lang.Long", "longValue", org.apache.bcel.generic.Type.LONG, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
}else if(returnType.equals("java.lang.String")){
throw new NotImplementedException(returnType);
}else if(returnType.equals("java.lang.Boolean")){
il.append(_cg.getInstructionFactory().createInvoke("java.lang.Boolean", "booleanValue", org.apache.bcel.generic.Type.BOOLEAN, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
}else{
throw new NotImplementedException(returnType);
}
return il;
}
} }
// ino.end // ino.end

View File

@ -11,6 +11,10 @@ import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
// ino.class.OrOp.24282.declaration // ino.class.OrOp.24282.declaration
public class OrOp extends LogOp public class OrOp extends LogOp
@ -27,6 +31,46 @@ public class OrOp extends LogOp
} }
// ino.end // ino.end
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
/*
0: aload_1
1: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z
4: ifne 14
7: aload_2
8: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z
11: ifeq 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokestatic #3 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
22: areturn
*/
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = operator.get_Expr1().genByteCode(_cg, rs);
il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.bcel.generic.Type.BOOLEAN, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
BranchInstruction firstTest = new IFNE(null);
il.append(firstTest);
il.append(operator.get_Expr2().genByteCode(_cg, rs));
il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.bcel.generic.Type.BOOLEAN, new org.apache.bcel.generic.Type[] {}, Constants.INVOKEVIRTUAL));
BranchInstruction secondTest = new IFEQ(null);
il.append(secondTest);
firstTest.setTarget(il.append(InstructionConstants.ICONST_1));
BranchInstruction gotoInstruction = new GOTO(null);
il.append(gotoInstruction);
secondTest.setTarget(il.append(InstructionConstants.ICONST_0));
gotoInstruction.setTarget(il.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.BOOLEAN}, Constants.INVOKESTATIC)));
return il;
}
} }
// ino.end // ino.end

View File

@ -1,7 +1,31 @@
// ino.module.PlusOp.8609.package // ino.module.PlusOp.8609.package
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.PlusOp.8609.import // ino.module.PlusOp.8609.import
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.DADD;
import org.apache.bcel.generic.FADD;
import org.apache.bcel.generic.GOTO;
import org.apache.bcel.generic.IADD;
import org.apache.bcel.generic.IFEQ;
import org.apache.bcel.generic.IFNE;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.InvokeInstruction;
import org.apache.bcel.generic.LADD;
import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.Type;
@ -19,5 +43,19 @@ public class PlusOp extends AddOp
super(offset,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
ArithmeticInstruction getOperator(String returnType) {
if(returnType.equals("java.lang.Integer")){
return new IADD();
}else if(returnType.equals("java.lang.Double")){
return new DADD();
}else if(returnType.equals("java.lang.Float")){
return new FADD();
}else if(returnType.equals("java.lang.Long")){
return new LADD();
}else{
throw new NotImplementedException();
}
}
} }
// ino.end // ino.end

View File

@ -2,11 +2,105 @@
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.RelOp.8610.import
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.GOTO;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
// ino.class.RelOp.24299.declaration // ino.class.RelOp.24299.declaration
public abstract class RelOp extends Operator public abstract class RelOp extends Operator
// ino.end // ino.end
// ino.class.RelOp.24299.body // ino.class.RelOp.24299.body
{ {
// ino.method.RelOp.24303.definition
public RelOp(int offset, int variableLength)
// ino.end
// ino.method.RelOp.24303.body
{
super(offset, variableLength);
}
// ino.end
protected Hashtable<RefType, RefType> getOperatorTypes() {
Hashtable<RefType, RefType> types = new Hashtable<RefType, RefType>();
types.put(new RefType("java.lang.Integer",this,-1), new RefType("java.lang.Boolean",this,-1));
types.put(new RefType("java.lang.Double",this,-1), new RefType("java.lang.Boolean",this,-1));
types.put(new RefType("java.lang.Float",this,-1), new RefType("java.lang.Boolean",this,-1));
types.put(new RefType("java.lang.Long",this,-1), new RefType("java.lang.Boolean",this,-1));
return types;
}
@Override
public HashMap<Type,Type> getReturnTypes(TypeAssumptions ass) {
HashMap<Type,Type> ret = new HashMap<>();
ret.put(new RefType("java.lang.Boolean",this,-1).TYPE(ass, this), new RefType("java.lang.Integer",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Boolean",this,-1).TYPE(ass, this), new RefType("java.lang.Double",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Boolean",this,-1).TYPE(ass, this), new RefType("java.lang.Float",this,-1).TYPE(ass, this));
ret.put(new RefType("java.lang.Boolean",this,-1).TYPE(ass, this), new RefType("java.lang.Long",this,-1).TYPE(ass, this));
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
/*
0: aload_1
1: invokevirtual #3 // Method java/lang/Integer.intValue:()I
4: aload_2
5: invokevirtual #3 // Method java/lang/Integer.intValue:()I
8: if_icmplt 15
11: iconst_1
12: goto 16
15: iconst_0
16: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
19: areturn
*/
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), "java.lang.Boolean");
il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), "java.lang.Boolean"));
BranchInstruction operatorBranchInstruction = getOperator();
il.append(operatorBranchInstruction);
il.append(InstructionConstants.ICONST_1);
BranchInstruction gotoInstruction = new GOTO(null);
il.append(gotoInstruction);
operatorBranchInstruction.setTarget(il.append(InstructionConstants.ICONST_0));
gotoInstruction.setTarget(il.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.bcel.generic.Type[] {org.apache.bcel.generic.Type.BOOLEAN}, Constants.INVOKESTATIC)));
return il;
}
abstract BranchInstruction getOperator();
} }
// ino.end // ino.end

View File

@ -2,7 +2,10 @@
package de.dhbwstuttgart.syntaxtree.operator; package de.dhbwstuttgart.syntaxtree.operator;
// ino.end // ino.end
// ino.module.TimesOp.8611.import // ino.module.TimesOp.8611.import
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import org.apache.bcel.generic.ArithmeticInstruction; import org.apache.bcel.generic.ArithmeticInstruction;
import org.apache.bcel.generic.DMUL; import org.apache.bcel.generic.DMUL;
import org.apache.bcel.generic.FMUL; import org.apache.bcel.generic.FMUL;
@ -22,9 +25,23 @@ public class TimesOp extends MulOp
// ino.end // ino.end
// ino.method.TimesOp.24316.body // ino.method.TimesOp.24316.body
{ {
super(offset,variableLength);
} }
// ino.end // ino.end
ArithmeticInstruction getOperator(String returnType) {
if(returnType.equals("java.lang.Integer")){
return new IMUL();
}else if(returnType.equals("java.lang.Double")){
return new DMUL();
}else if(returnType.equals("java.lang.Float")){
return new FMUL();
}else if(returnType.equals("java.lang.Long")){
return new LMUL();
}else{
throw new NotImplementedException();
}
}
} }
// ino.end // ino.end

View File

@ -1,17 +1,96 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import java.util.Iterator;
import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import java.util.List; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
public class ArgumentList extends SyntaxTreeNode public class ArgumentList extends SyntaxTreeNode
{ {
public ArgumentList(int offset) { public ArgumentList(int offset) {
super(offset);
} }
public List<Expr> expr; public Menge<Expr> expr = new Menge<Expr>();
public Object get_firstElement()
{
return expr.firstElement();
}
/**
* @author Andreas Stadelmeier, a10023
* @return Anzahl der Argumente in der ArgumentList
*/
public int size() {
return expr.size();
}
/**
* @author Andreas Stadelmeier, a10023
* @param n
* @return Das Element (Expr) in der Argumentliste an der Stelle n
*/
public Expr argumentAt(int n){
return expr.elementAt(n);
}
public String toString(){
if(expr == null)return "[]";
String ret = " [ ";
for(Expr expr : this.expr){
ret += expr.toString()+", ";
}
return ret + "]";
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
Iterator<Expr> it = this.expr.iterator();
while(it.hasNext()){
Expr expr = it.next();
ret.attach(expr.printJavaCode(resultSet));
if(it.hasNext())ret.attach(", ");
}
//if(this.expr.size()>0)ret = ret.substring(0, ret.length()-2);
return ret;
}
@Override
public int getOffset() {
return 0;
}
@Override
public Menge<? extends SyntaxTreeNode> getChildren() {
return expr;
}
public InstructionList generateBytecode(ClassGenerator cg, TypeinferenceResultSet rs){
InstructionList ret = new InstructionList();
for(Expr e : expr){
ret.append(e.genByteCode(cg, rs));
}
return ret;
}
public org.apache.bcel.generic.Type[] getBytecodeTypeList(ClassGenerator cg, TypeinferenceResultSet rs){
org.apache.bcel.generic.Type[] ret = new org.apache.bcel.generic.Type[expr.size()];
int i = 0;
for(Expr e : expr){
ret[i] = e.getType().getBytecodeType(cg, rs);
i++;
}
return ret;
}
} }

View File

@ -1,14 +1,27 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
public class Assign extends ExprStmt public class Assign extends ExprStmt
{ {
public Assign(RefType type, int offset) { public Assign(Type type, int offset) {
super(type, offset); super(type, offset);
} }
@ -17,6 +30,7 @@ public class Assign extends ExprStmt
/** /**
* Logger log4j * Logger log4j
*/ */
protected static Logger parserlog = Logger.getLogger("parser");
public void set_Expr(Expr expr1,Expr expr2) public void set_Expr(Expr expr1,Expr expr2)
@ -31,6 +45,119 @@ public class Assign extends ExprStmt
} }
/**
* @author AI10023 - Andreas Stadelmeier
*/
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
ret.add(expr1.TYPEExpr(assumptions));
ret.add(expr2.TYPEExpr(assumptions));
//this.setTypeVariable( TypePlaceholder.fresh(this));
//this.setType(TypePlaceholder.fresh(this));
ret.add(ConstraintsSet.createSingleConstraint(expr2.getType().TYPE(assumptions, this), expr1.getType().TYPE(assumptions, this))); //expr2.type <. expr1.type
ret.add(ConstraintsSet.createSingleConstraint(expr1.getType().TYPE(assumptions, this), this.getType().TYPE(assumptions, this)));
return ret;
}
/**
* Spezifikation:
* TYPEStmt( Ass, stmt ) =
* let (stmt : rty, ConS) = TYPEExpr( Ass, stmt )
* in (stmt : Void, ConS)
*/
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions){
ConstraintsSet ret = this.TYPEExpr(assumptions); //TypeExpr aufrufen
//this.setType(new Void(0)); //Typ des Statments auf Void setzen.
return ret;
}
// ino.method.toString.24960.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.24960.definition
public String toString()
// ino.end
// ino.method.toString.24960.body
{
if(getType() == null)return "(" + expr1.toString() + " = " + expr2.toString() + ")";
return getType().toString() + "(" + expr1.toString() + " = " + expr2.toString() + ")";
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.24963.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.24963.body
{
}
// ino.end
/*
@Override
public String getTypeInformation(){
return "(" + expr1.getTypeInformation() + " = " + expr2.getTypeInformation() + ") : "+this.getType();
}
*/
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet){
JavaCodeResult ret = new JavaCodeResult().attach(this.expr1.printJavaCode(resultSet) ).attach( " = " ).attach( this.expr2.printJavaCode(resultSet));
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr1);
ret.add(this.expr2);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
DHBWInstructionFactory _factory = new DHBWInstructionFactory(cg, cg.getConstantPool());
InstructionList il = expr2.genByteCode(cg, rs);//expr2 rechte expr
/*
String expr2Type = expr2.getType().get_Name().toString();
switch(expr2Type){
case "java.lang.Integer":
il.append(new ISTORE(counterAssign));
break;
case "java.lang.String":
il.append(new ASTORE(counterAssign));
break;
case "java.lang.Double":
il.append(new DSTORE(counterAssign));
break;
case "java.lang.Float":
il.append(new FSTORE(counterAssign));
break;
case "java.lang.Long":
il.append(new LSTORE(counterAssign));
break;
}
*/
//Es wird momentan immer von RefType ausgegangen:
il.append(cg.getMethodGenerator().createStore(expr2.getType().getBytecodeType(cg, rs), expr1.get_Name()));
return il;
}
} }
// ino.end // ino.end

View File

@ -7,8 +7,20 @@ import java.util.HashMap;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.operator.Operator; import de.dhbwstuttgart.syntaxtree.operator.Operator;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
// ino.class.Binary.24966.description type=line // ino.class.Binary.24966.description type=line
@ -30,6 +42,168 @@ public class Binary extends BinaryExpr
// ino.end // ino.end
// ino.attribute.parserlog.24973.decldescription type=javadoc
/**
* Logger: log4j
*/
// ino.end
// ino.attribute.parserlog.24973.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.attribute.expr1.24976.declaration
public Expr expr1;
// ino.end
// ino.attribute.op.24979.declaration
public Operator op;
// ino.end
// ino.attribute.expr2.24982.declaration
public Expr expr2;
// ino.end
// ino.method.set_Expr1.24988.definition
public void set_Expr1(Expr exp)
// ino.end
// ino.method.set_Expr1.24988.body
{
this.expr1=exp;
}
// ino.end
// ino.method.set_Expr2.24991.definition
public void set_Expr2(Expr exp)
// ino.end
// ino.method.set_Expr2.24991.body
{
this.expr2=exp;
}
// ino.end
// ino.method.set_Operator.24994.definition
public void set_Operator(Operator Op)
// ino.end
// ino.method.set_Operator.24994.body
{
this.op=Op;
}
// ino.end
// ino.method.get_Name.24997.definition
public String get_Name()
// ino.end
// ino.method.get_Name.24997.body
{
return null;
}
// ino.end
// ino.method.get_Operator.25000.definition
public Operator get_Operator()
// ino.end
// ino.method.get_Operator.25000.body
{
return op;
}
// ino.end
// ino.method.get_Expr1.25003.definition
public Expr get_Expr1()
// ino.end
// ino.method.get_Expr1.25003.body
{
return expr1;
}
// ino.end
// ino.method.get_Expr2.25006.definition
public Expr get_Expr2()
// ino.end
// ino.method.get_Expr2.25006.body
{
return expr2;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25027.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25027.body
{
}
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
ret.add(this.expr1.TYPEExpr(assumptions));
ret.add(this.expr2.TYPEExpr(assumptions));
/**
* Berechnet die Constraints dieses Operators ¼r die 2 gegebenen Parameter
* Die Operatoren sind meistens überladen. Es entstehen mehrere Oder-Verknüpfte Constraints.
* @param expr1
* @param expr2
* @return
*/
//if(this.getType()==null)this.set_Type(TypePlaceholder.fresh(this));
OderConstraint oderCons = new OderConstraint();
HashMap<Type,Type> rMap = this.op.getReturnTypes(assumptions);
for(Type rT : rMap.keySet()){
UndConstraint c = new UndConstraint();
c.addConstraint(this.getType().TYPE(assumptions, this),rT);
c.addConstraint(this.expr1.getType().TYPE(assumptions, this), rMap.get(rT));
c.addConstraint(this.expr2.getType().TYPE(assumptions, this), rMap.get(rT));
oderCons.addConstraint(c);
}
ret.add(oderCons);
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
ret.attach(this.expr1.printJavaCode(resultSet)).attach(" ");
ret.attach(this.op.toString()+" ");
ret.attach(this.expr2.printJavaCode(resultSet));
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr1);
ret.add(this.expr2);
return ret;
}
private InstructionList genUnboxByteCode(ClassGen _cg, Type t){
return null;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
return op.genByteCode(_cg, rs, this);
}
} }
// ino.end // ino.end

View File

@ -1,6 +1,8 @@
// ino.module.BinaryExpr.8624.package // ino.module.BinaryExpr.8624.package
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
// ino.class.BinaryExpr.25030.declaration // ino.class.BinaryExpr.25030.declaration
@ -14,7 +16,7 @@ public abstract class BinaryExpr extends Expr
// ino.end // ino.end
// ino.method.BinaryExpr.25034.body // ino.method.BinaryExpr.25034.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end

View File

@ -2,7 +2,10 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
// ino.end // ino.end
// ino.module.Block.8625.import // ino.module.Block.8625.import
import java.util.*; import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
@ -12,6 +15,25 @@ import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.MethodGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
@ -25,15 +47,29 @@ public class Block extends Statement
private ClassGen _cg; private ClassGen _cg;
public Block(List<Statement> statements, int offset) { public Block(List<Statement> statements, int offset) {
super(null, 0); super(offset);
this.statements = statements; this.statements = statements;
} }
// ino.attribute.parserlog.25044.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
public List<Statement> statements = new ArrayList<>(); public List<Statement> statements = new Menge<Statement>();
//private String sc_meth_ret_type;
// ino.attribute.inferencelog.25059.decldescription type=javadoc
/**
* Logger: log4j
*/
// ino.end
// ino.attribute.inferencelog.25059.declaration
protected static Logger inferencelog = Logger.getLogger("inference");
// ino.end
protected static Logger typinferenceLog = Logger.getLogger("Typeinference");
// ino.method.get_Statement.25065.definition // ino.method.get_Statement.25065.definition
@ -50,6 +86,125 @@ public class Block extends Statement
// ino.method.toString.25083.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25083.definition
public String toString()
// ino.end
// ino.method.toString.25083.body
{
return this.type + " { " + statements.toString();
}
// ino.end
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
/* this.setTypeVariable(TypePlaceholder.fresh(this)); */
for(Statement stmt : statements){
typinferenceLog.debug("Prozessing statement: "+stmt, Section.TYPEINFERENCE);
ret.add(stmt.TYPEStmt(assumptions));
/* if((stmt instanceof Return)){
ret.add(new Constraint(stmt.getTypeVariable(), this.getTypeVariable()));//TODO: Dies nochmal prüfen.
}
*/
}
if(statements.size()>0){
Statement stmt = statements.get(statements.size()-1);
typinferenceLog.debug("Prozessing statement: "+stmt, Section.TYPEINFERENCE);
this.setType(stmt.getType());
for(int i= statements.size()-2; i >= 0; i--) {
stmt = statements.get(i);
typinferenceLog.debug("Prozessing statement: "+stmt, Section.TYPEINFERENCE);
if (!(stmt.getReturnType() instanceof Void))
if (this.getReturnType() instanceof Void) {
//this.setTypeVariable(stmt.getTypeVariable());
throw new TypeinferenceException("Block besitzt falschen Rückgabetyp (fehlendes return-stmt)", this);
}
else {
TypePlaceholder tph = TypePlaceholder.fresh(this);
ret.add(ConstraintsSet.createSingleConstraint(this.getType().TYPE(assumptions, this), tph));
ret.add(ConstraintsSet.createSingleConstraint(stmt.getType().TYPE(assumptions, this), tph));
this.setType(tph);
}
}
}
return ret;
}
/*
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
if(this.getTypeVariable()==null)this.setTypeVariable(TypePlaceholder.fresh(this));
for(Statement stmt : statements){
typinferenceLog.debug("Prozessing statement: "+stmt);
ret.add(stmt.TYPEStmt(assumptions));
if((stmt instanceof Return)){
ret.add(new Constraint(stmt.getTypeVariable(), this.getTypeVariable()));//TODO: Dies nochmal prüfen.
}
}
return ret;
}
*/
@Override
public String getTypeInformation(){
String ret = "\n";
for(Statement s : this.get_Statement()){
ret += s.getTypeInformation()+"\n";
}
return ret;
}
public int getTypeLineNumber() {
throw new NotImplementedException();
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult().attach("{\n");
for(Statement stmt : this.get_Statement()){
ret.attach(stmt.printJavaCode(resultSet));
ret.attach((stmt instanceof ExprStmt ? ";" : "") + "\n");
}
return ret.attach("}");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
for(Statement st : this.get_Statement()){
ret.add(st);
}
return ret;
}
@Override
public String getDescription(){
return "Block";
}
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
//ConstantPoolGen _cp = cg.getConstantPool();
InstructionList il = new InstructionList();
for(Statement stmt : this.get_Statement()){
il.append(stmt.genByteCode(cg, rs));
}
//il.dispose();
return il;
}
} }
// ino.end // ino.end

View File

@ -9,6 +9,20 @@ import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -19,14 +33,27 @@ public class BoolLiteral extends Literal
{ {
// ino.attribute.Bool.25093.declaration
private boolean Bool; private boolean Bool;
// ino.end
// ino.attribute.parserlog.25096.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.BoolLiteral.25099.definition // ino.method.BoolLiteral.25099.definition
public BoolLiteral() public BoolLiteral()
// ino.end // ino.end
// ino.method.BoolLiteral.25099.body // ino.method.BoolLiteral.25099.body
{ {
super(null,-1); super(-1,-1);
// #JB# 20.04.2005
// ###########################################################
this.setType(new RefType("java.lang.Boolean",this.getOffset()));
//this.setType(new Type("boolean"));
// ###########################################################
} }
// ino.end // ino.end
@ -64,10 +91,45 @@ public class BoolLiteral extends Literal
{ {
return null; return null;
} }
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
return new ConstraintsSet();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
if(Bool)return new JavaCodeResult("true");
return new JavaCodeResult("false");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = new InstructionFactory(_cg, _cg.getConstantPool());
InstructionList il = new InstructionList();
if (Bool == true){
il.append(InstructionConstants.ICONST_1);
}else {
il.append(InstructionConstants.ICONST_0);
}
return il;
}
} }
// ino.end // ino.end

View File

@ -5,10 +5,24 @@ package de.dhbwstuttgart.syntaxtree.statement;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
// ino.class.CastExpr.25126.declaration // ino.class.CastExpr.25126.declaration
@ -17,19 +31,24 @@ public class CastExpr extends Expr
// ino.class.CastExpr.25126.body // ino.class.CastExpr.25126.body
{ {
// ino.method.CastExpr.25130.definition // ino.method.CastExpr.25130.definition
public CastExpr(RefType castType, Expr expr, int offset) public CastExpr(Type castType, Expr expr,int offset)
// ino.end // ino.end
// ino.method.CastExpr.25130.body // ino.method.CastExpr.25130.body
{ {
super(null, 0); super(offset);
this.type = castType;
} }
// ino.end // ino.end
// ino.attribute.type.25133.decla // ino.attribute.type.25133.declaration
private Type type;
// ino.end // ino.end
// ino.attribute.expr.25136.declaration // ino.attribute.expr.25136.declaration
public Expr expr; public Expr expr;
// ino.end // ino.end
// ino.attribute.parserlog.25139.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
@ -44,7 +63,16 @@ public class CastExpr extends Expr
// ino.end // ino.end
// ino.method.set_Type.25148.definition
public void set_Type(Type ty)
// ino.end
// ino.method.set_Type.25148.body
{
this.type = ty;
}
// ino.end
// ino.method.set_Expr.25151.definition // ino.method.set_Expr.25151.definition
@ -57,6 +85,46 @@ public class CastExpr extends Expr
// ino.end // ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25163.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25163.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("(("+this.+")").attach(this.expr.printJavaCode(resultSet)).attach(")");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -4,6 +4,24 @@ package de.dhbwstuttgart.syntaxtree.statement;
// ino.module.CharLiteral.8628.import // ino.module.CharLiteral.8628.import
import java.util.Hashtable; import java.util.Hashtable;
import org.apache.bcel.generic.BIPUSH;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -15,6 +33,10 @@ public class CharLiteral extends Literal
{ {
// ino.attribute.Char.25170.declaration // ino.attribute.Char.25170.declaration
private char Char; private char Char;
// ino.end
// ino.attribute.parserlog.25173.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.CharLiteral.25176.definition // ino.method.CharLiteral.25176.definition
@ -22,7 +44,11 @@ public class CharLiteral extends Literal
// ino.end // ino.end
// ino.method.CharLiteral.25176.body // ino.method.CharLiteral.25176.body
{ {
super(null,-1); super(-1,-1);
// #JB# 20.04.2005
// ###########################################################
this.setType(new RefType("Char",this,this.getOffset()));
//this.setType(new Type("char"));
// ########################################################### // ###########################################################
} }
// ino.end // ino.end
@ -58,6 +84,50 @@ public class CharLiteral extends Literal
return null; return null;
} }
// ino.end // ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("'"+String.valueOf(this.Char)+"'");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public void wandleRefTypeAttributes2GenericAttributes(
Menge<Type> paralist,
Menge<GenericTypeVar> genericMethodParameters) {
}
//Char-Getter fuer genByteCode
public char get_Char()
// ino.end
// ino.method.get_Int.25463.body
{
return Char;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = new InstructionFactory(_cg, _cg.getConstantPool());
InstructionList il = new InstructionList();
il.append(new BIPUSH((byte) get_Char()));
return il;
}
} }
// ino.end // ino.end

View File

@ -11,8 +11,20 @@ import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LDC; import org.apache.bcel.generic.LDC;
import org.apache.bcel.generic.LDC2_W; import org.apache.bcel.generic.LDC2_W;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -24,14 +36,20 @@ public class DoubleLiteral extends Literal
{ {
// ino.attribute.Int.25451.declaration // ino.attribute.Int.25451.declaration
private double Double; private double Double;
// ino.end
// ino.attribute.parserlog.25454.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.IntLiteral.25457.definition // ino.method.IntLiteral.25457.definition
public DoubleLiteral() public DoubleLiteral()
// ino.end // ino.end
// ino.method.IntLiteral.25457.body // ino.method.IntLiteral.25457.body
{ {
super(null,-1); super(-1,-1);
this.setType(new RefType("Double",this,this.getOffset()));
} }
// ino.end // ino.end
@ -75,6 +93,65 @@ public class DoubleLiteral extends Literal
// ino.end // ino.end
// ino.method.toString.25484.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25484.definition
public String toString()
// ino.end
// ino.method.toString.25484.body
{
return type.toString() + " " + Double;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
this.setType(assumptions.checkType(new RefType("Double",this,this.getOffset()), this));
return new ConstraintsSet();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
ret.attach(""+this.Double);
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
//alter Double-Versuch vermutlich inkorrekt
/*@Override
public InstructionList genByteCode(ClassGen cg) {
InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool());
InstructionList il = new InstructionList();
il.append(new BIPUSH(new Double(get_Double()).byteValue()));
return il;
}*/
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
ConstantPoolGen cp = _cg.getConstantPool();
//InstructionFactory _factory = new InstructionFactory(cg, cp);
InstructionList il = new InstructionList();
cp.addDouble(get_Double());
il.append(new LDC2_W(cp.getSize()-1));
return il;
}
} }
// ino.end // ino.end

View File

@ -7,6 +7,19 @@ import java.util.Hashtable;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -21,12 +34,63 @@ public class EmptyStmt extends Statement
// ino.end // ino.end
// ino.method.EmptyStmt.25207.body // ino.method.EmptyStmt.25207.body
{ {
super(null,-1); super(-1,-1);
} }
// ino.end // ino.end
// ino.attribute.parserlog.25210.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
/*
// ino.method.sc_check.25213.definition
public void sc_check(Menge<Class> classlist, Hashtable ch, Hashtable<String, String> bh, boolean ext, Hashtable parach, Hashtable<String, Hashtable> parabh)
// ino.end
// ino.method.sc_check.25213.body
{
if(ext){
parserlog.debug(" ---EmptyStmt---");
}
}
// ino.end
*/
// ino.method.wandleRefTypeAttributes2GenericAttributes.25222.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25222.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
public int getTypeLineNumber() {
throw new NotImplementedException();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
return new Menge<SyntaxTreeNode>();
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -2,18 +2,35 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.Typeable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
public abstract class Executeable extends SyntaxTreeNode public abstract class Executeable extends SyntaxTreeNode implements Typeable
{ {
private RefType type; private Type type;
public Executeable(RefType type, int offset) { public Executeable(Type type,int offset) {
super(offset);
this.type = type; this.type = type;
} }
public Type getType(){
return type;
}
public abstract InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs);
//public abstract String getTypeInformation(); //public abstract String getTypeInformation();
} }

View File

@ -4,17 +4,32 @@ package de.dhbwstuttgart.syntaxtree.statement;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
public abstract class Expr extends Executeable public abstract class Expr extends Executeable
{ {
public Expr(RefType type, int offset) { public Expr(Type type, int offset) {
super(type, offset); super(type, offset);
} }
public abstract String get_Name();
/**
* @author AI10023 - Andreas Stadelmeier
* Implementierung des Java 8 - Typinferenzalgorithmus von Martin Plümicke
* Jede Expression wird im Zuge des Algorithmus durch die TYPEExpr-Funktion angesprochen.
*/
public abstract ConstraintsSet TYPEExpr(TypeAssumptions assumptions);
} }

View File

@ -1,10 +1,14 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
public abstract class ExprStmt extends Executeable{ public abstract class ExprStmt extends Executeable{
public ExprStmt(RefType type, int offset) { public ExprStmt(Type type,int offset) {
super(type, offset); super(type,offset);
} }
public abstract ConstraintsSet TYPEExpr(TypeAssumptions assumptions);
public abstract ConstraintsSet TYPEStmt(TypeAssumptions assumptions);
} }

View File

@ -10,6 +10,20 @@ import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LDC; import org.apache.bcel.generic.LDC;
import org.apache.bcel.generic.LDC2_W; import org.apache.bcel.generic.LDC2_W;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -20,14 +34,20 @@ public class FloatLiteral extends Literal
{ {
// ino.attribute.Int.25451.declaration // ino.attribute.Int.25451.declaration
private float Float; private float Float;
// ino.end
// ino.attribute.parserlog.25454.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.IntLiteral.25457.definition // ino.method.IntLiteral.25457.definition
public FloatLiteral() public FloatLiteral()
// ino.end // ino.end
// ino.method.IntLiteral.25457.body // ino.method.IntLiteral.25457.body
{ {
super(null,-1); super(-1,-1);
this.setType(new RefType("Float",this,this.getOffset()));
} }
// ino.end // ino.end
@ -71,5 +91,54 @@ public class FloatLiteral extends Literal
// ino.end // ino.end
// ino.method.toString.25484.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25484.definition
public String toString()
// ino.end
// ino.method.toString.25484.body
{
return type.toString() + " " + Float;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
ConstantPoolGen cp = _cg.getConstantPool();
InstructionList il = new InstructionList();
cp.addFloat(get_Float());
il.append(new LDC(cp.getSize()-1));
return il;
}
} }
// ino.end // ino.end

View File

@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree.statement;
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.List;
import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
@ -13,7 +12,28 @@ import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.NOP; import org.apache.bcel.generic.NOP;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.operator.LogOp;
import de.dhbwstuttgart.syntaxtree.operator.Operator;
import de.dhbwstuttgart.syntaxtree.operator.RelOp;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
public class ForStmt extends Statement public class ForStmt extends Statement
{ {
@ -28,13 +48,113 @@ public class ForStmt extends Statement
public ForStmt(int offset, int variableLength) public ForStmt(int offset, int variableLength)
{ {
super(null,variableLength); super(offset,variableLength);
} }
void sc_check(List<Class> classname, Hashtable ch, Hashtable<String, String> bh, boolean ext, Hashtable parach, Hashtable<String, Hashtable> parabh) void sc_check(Menge<Class> classname, Hashtable ch, Hashtable<String, String> bh, boolean ext, Hashtable parach, Hashtable<String, Hashtable> parabh)
{ {
}
public String toString()
{
return "FOR ";
}
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
{
if(body_Loop_block!=null){
body_Loop_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters);
}
} }
public void set_head_Initializer(Expr expr) {
head_Initializer = expr;
}
public void set_head_Condition(Expr expr) {
head_Condition = expr;
}
public void set_head_Loop_expr(Expr expr) {
head_Loop_expr = expr;
}
public void set_body_Loop_block(Statement statement) {
body_Loop_block = statement;
}
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
//TODO: TYPEStmt
ConstraintsSet ret = new ConstraintsSet();
this.setType(TypePlaceholder.fresh(this));
ret.add(body_Loop_block.TYPEStmt(assumptions));
return ret;
}
public int getTypeLineNumber() {
throw new NotImplementedException();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO printJavaCode
return new JavaCodeResult();
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
if(this.body_Loop_block!=null)ret.add(this.body_Loop_block);
if(this.head_Condition!=null)ret.add(this.head_Condition);
if(this.head_Condition_1!=null)ret.add(this.head_Condition_1);
if(this.head_Initializer!=null)ret.add(this.head_Initializer);
if(this.head_Initializer_1!=null)ret.add(this.head_Initializer_1);
if(this.head_Loop_expr!=null)ret.add(this.head_Loop_expr);
if(this.head_Loop_expr_1!=null)ret.add(this.head_Loop_expr_1);
//throw new NotImplementedException();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
/*
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 14
8: iinc 1, 1
11: goto 2
14: return
*/
InstructionList il = new InstructionList();
il.append(head_Initializer.genByteCode(_cg, rs));
InstructionHandle ih = il.append(head_Condition.genByteCode(_cg, rs));
BranchInstruction branch = new IF_ICMPGE(null);
il.append(branch);
il.append(body_Loop_block.genByteCode(_cg, rs));
il.append(head_Loop_expr.genByteCode(_cg, rs));
il.append(new GOTO(ih));
branch.setTarget(il.append(new NOP()));
return il;
}
} }

View File

@ -22,6 +22,30 @@ import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.NOP; import org.apache.bcel.generic.NOP;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.operator.LogOp;
import de.dhbwstuttgart.syntaxtree.operator.Operator;
import de.dhbwstuttgart.syntaxtree.operator.RelOp;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
// ino.class.IfStmt.25300.declaration // ino.class.IfStmt.25300.declaration
@ -34,7 +58,7 @@ public class IfStmt extends Statement
// ino.end // ino.end
// ino.method.IfStmt.25304.body // ino.method.IfStmt.25304.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
@ -50,6 +74,9 @@ public class IfStmt extends Statement
// ino.attribute.else_block.25316.declaration // ino.attribute.else_block.25316.declaration
public Statement else_block; public Statement else_block;
// ino.end // ino.end
// ino.attribute.parserlog.25319.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
@ -72,6 +99,101 @@ public class IfStmt extends Statement
this.then_block = blk; this.then_block = blk;
} }
// ino.end // ino.end
// ino.method.set_Else_block.25328.definition
public void set_Else_block(Statement blk)
// ino.end
// ino.method.set_Else_block.25328.body
{
this.else_block = blk;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25349.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25349.body
{
if(then_block!=null){
then_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters);
}
if(else_block!=null){
else_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters);
}
}
// ino.end
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
this.setType(TypePlaceholder.fresh(this));
ret.add(expr.TYPEExpr(assumptions)); // die Constraints ¼r (expressionDesIfStmt)
ret.add(this.then_block.TYPEStmt(assumptions));
if(else_block!=null){
ret.add(this.else_block.TYPEStmt(assumptions));
if(!(else_block.getType() instanceof Void))ret.add(ConstraintsSet.createSingleConstraint(else_block.getType().TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
}
ret.add(ConstraintsSet.createSingleConstraint(expr.getType().TYPE(assumptions, this),new RefType("Boolean",this,0).TYPE(assumptions, this))); //(expressionDesIfStmt)<.boolean
if(!(then_block.getType() instanceof Void))ret.add(ConstraintsSet.createSingleConstraint(then_block.getType().TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
if(then_block.getType() instanceof Void &&
(else_block == null || else_block.getType() instanceof Void))this.setType(new Void(this,this.getOffset()));
return ret;
}
public int getTypeLineNumber() {
throw new NotImplementedException();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult("If(").attach(this.expr.printJavaCode(resultSet)).attach("){\n");
if(this.then_block!=null)ret.attach(this.then_block.printJavaCode(resultSet));
ret.attach("\n}else{\n");
if(this.else_block!=null)ret.attach(this.else_block.printJavaCode(resultSet));
ret.attach("\n}");
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
if(this.expr!=null)ret.add(this.expr);
if(this.else_block!=null)ret.add(this.else_block);
if(this.then_block!=null)ret.add(this.then_block);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = new InstructionList();
IfInstruction ifInstruction = new IFEQ(null);
il.append(expr.genByteCode(_cg, rs));
//Anmerkung: expr ist vom Typ java.lang.Boolean (per Definition)
il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.bcel.generic.Type.BOOLEAN, org.apache.bcel.generic.Type.NO_ARGS, Constants.INVOKEVIRTUAL));
il.append(ifInstruction);
il.append(then_block.genByteCode(_cg, rs));
if(else_block != null && !(else_block instanceof EmptyStmt)){
//GotoInstruction gotoInstruction = new GOTO(null);
//il.append(gotoInstruction);
ifInstruction.setTarget(il.append(else_block.genByteCode(_cg, rs)));
//gotoInstruction.setTarget(il.append(new NOP()));
}else{
ifInstruction.setTarget(il.append(new NOP()));
}
return il;
}
} }
// ino.end // ino.end

View File

@ -9,6 +9,28 @@ import java.util.Iterator;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
@ -20,17 +42,176 @@ public class InstVar extends Expr
// ino.attribute.expr.25396.declaration // ino.attribute.expr.25396.declaration
private Expr expr; private Expr expr;
// ino.end // ino.end
// ino.attribute.usedid.25399.declaration
private UsedId usedid;
// ino.end
// ino.attribute.type.25402.declaration // ino.attribute.type.25402.declaration
protected String type; //???? BRAUCHT MAN DEN??? protected String type; //???? BRAUCHT MAN DEN???
// ino.end // ino.end
// ino.attribute.parserlog.25405.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.InstVar.25408.definition // ino.method.InstVar.25408.definition
public InstVar(Expr e, String n, int offset) public InstVar(Expr e, String n, int offset)
// ino.end // ino.end
// ino.method.InstVar.25408.body // ino.method.InstVar.25408.body
{ {
super(null,n.length()); super(offset,n.length());
expr = e; expr = e;
usedid = new UsedId(getOffset());
usedid.set_Name(n);
} }
// ino.end
// ino.method.InstVar.25411.definition
public InstVar(String n, String t, int offset)
// ino.end
// ino.method.InstVar.25411.body
{
super(offset,n.length());
usedid = new UsedId(getOffset());
usedid.set_Name(n);
type = t;
}
// ino.end
// ino.method.InstVar.25414.defdescription type=javadoc
/**
* macht aus einem UsedId mit einem Menge von Strings eine InstVar
* <br/>Author: Martin Pl�micke PL 05-08-17
* @param ui
* @return
*/
// ino.end
// ino.method.InstVar.25414.definition
public InstVar(UsedId ui, int offset,int variableLength)
// ino.end
// ino.method.InstVar.25414.body
{
super(offset,variableLength);
Iterator namen = ui.get_Name().iterator();
LocalOrFieldVarOrClassname innerLOFV = new LocalOrFieldVarOrClassname((String)namen.next(),getOffset());
//innerLOFV.setType(TypePlaceholder.fresh(this));
InstVar INSTVA = new InstVar(innerLOFV, (String)namen.next(),offset);
//INSTVA.setType(TypePlaceholder.fresh(this));
while(namen.hasNext()) {
INSTVA = new InstVar(INSTVA, (String)namen.next(),offset);
//INSTVA.setType(TypePlaceholder.fresh(this));
}
expr = INSTVA.expr;
usedid = INSTVA.usedid;
}
// ino.end
@Override
public void parserPostProcessing(SyntaxTreeNode parent) {
super.parserPostProcessing(parent);
if(this.getType()==null)this.set_Type(TypePlaceholder.fresh(this));
}
/*
// ino.method.sc_check.25417.definition
public void sc_check(Menge<Class> classname, Hashtable ch, Hashtable<String, String> bh, boolean ext, Hashtable parach, Hashtable<String, Hashtable> parabh)
// ino.end
// ino.method.sc_check.25417.body
{
if(ext)
parserlog.debug(" ---InstVar---");
Menge name = usedid.get_Name();
for(Enumeration el = name.elements(); el.hasMoreElements();)
{
String name1 = (String) el.nextElement();
if(bh.containsKey(name1))
{
this.type = (String)bh.get(name1); //type wird von Expr geerbt
if(ext)
parserlog.debug("Variable " + name1 + " im Block gefunden.");
}
else if(ch.containsKey(name1))
{
this.type = (String)ch.get(name1);
if(ext)
parserlog.debug("Variable " + name1 + " in Class gefunden.");
}
else
if(ext)
parserlog.debug("Typfehler: -->InstVar.sc_check() "+ name1);
}
}
// ino.end
*/
// ino.method.get_Name.25420.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25420.body
{
return this.usedid.get_Name_1Element();
}
// ino.end
// ino.method.get_codegen_UsedId.25423.definition
public String get_codegen_UsedId()
// ino.end
// ino.method.get_codegen_UsedId.25423.body
{ return usedid.get_codegen_UsedId(); }
// ino.end
// ino.method.toString.25441.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
public String toString()
{
String superType = "";
if(super.type != null)superType += super.type.toString();
return superType + " " + usedid.toString();
}
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
{
}
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
if(this.expr == null){
this.expr = new This(0, 0);
}
ret.add(expr.TYPEExpr(assumptions));
this.setType(TypePlaceholder.fresh(this));
OderConstraint oderConstraint = new OderConstraint();
for(FieldAssumption fa : assumptions.getFieldVars(this.get_Name())){
UndConstraint undConstraint = new UndConstraint();
undConstraint.addConstraint(fa.getAssumedType().TYPE(assumptions, this),this.getType().TYPE(assumptions, this));
undConstraint.addConstraint(this.expr.getType().TYPE(assumptions, this),fa.getParentClass().getType().TYPE(assumptions, this));
oderConstraint.addConstraint(undConstraint);
}
ret.add(oderConstraint);
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
if(this.expr != null)ret.attach(this.expr.printJavaCode(resultSet)).attach(".");
return ret.attach(this.usedid.get_Name_1Element());
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -8,7 +8,20 @@ import java.util.Hashtable;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -26,6 +39,9 @@ public class InstanceOf extends BinaryExpr
// ino.attribute.parserlog.25362.decldescription type=line // ino.attribute.parserlog.25362.decldescription type=line
// private boolean is_instance = false; // private boolean is_instance = false;
// ino.end // ino.end
// ino.attribute.parserlog.25362.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.InstanceOf.25365.definition // ino.method.InstanceOf.25365.definition
@ -35,6 +51,10 @@ public class InstanceOf extends BinaryExpr
{ {
super(offset,variableLength); super(offset,variableLength);
// #JB# 20.04.2005 // #JB# 20.04.2005
// ###########################################################
this.setType(new RefType("Boolean",this,this.getOffset()));
//this.setType(new Type("boolean"));
// ###########################################################
} }
// ino.end // ino.end
@ -66,6 +86,41 @@ public class InstanceOf extends BinaryExpr
} }
// ino.end // ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25389.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25389.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -11,6 +11,21 @@ import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -23,14 +38,22 @@ public class IntLiteral extends Literal
// ino.attribute.Int.25451.declaration // ino.attribute.Int.25451.declaration
private int Int; private int Int;
// ino.end // ino.end
// ino.attribute.parserlog.25454.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.IntLiteral.25457.definition // ino.method.IntLiteral.25457.definition
public IntLiteral() public IntLiteral()
// ino.end // ino.end
// ino.method.IntLiteral.25457.body // ino.method.IntLiteral.25457.body
{ {
super(null,-1); super(-1,-1);
// #JB# 20.04.2005 // #JB# 20.04.2005
// ###########################################################
this.setType(new RefType("Integer",this,this.getOffset()));
//this.setType(new Type("int"));
// ###########################################################
} }
// ino.end // ino.end
@ -73,5 +96,58 @@ public class IntLiteral extends Literal
// ino.end // ino.end
// ino.method.toString.25484.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25484.definition
public String toString()
// ino.end
// ino.method.toString.25484.body
{
return getType().toString() + " " + Int;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
//this.setType(new IntegerType());
this.set_Type(assumptions.checkType(new RefType("java.lang.Integer",this,-1), this));
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult(String.valueOf(this.Int));
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool());
InstructionList il = new InstructionList();
/*
* Der jetzige Compiler kann keine primitiven Typen. Ein int-Literal ist daher eine Instanz von java.lang.Integer
*/
il.append(new PUSH(cg.getConstantPool(), this.get_Int()));
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.INT }, Constants.INVOKESTATIC));
return il;
}
} }
// ino.end // ino.end

View File

@ -10,14 +10,29 @@ import org.apache.bcel.classfile.InnerClass;
import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.MethodGenerator;
import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassHelper;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.FunVoidN; import de.dhbwstuttgart.syntaxtree.type.FunVoidN;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.ObjectType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
/** /**
* @author A10023 - Andreas Stadelmeier * @author A10023 - Andreas Stadelmeier
@ -38,9 +53,247 @@ public class LambdaExpression extends Expr{
private ParameterList params; private ParameterList params;
public LambdaExpression(int offset, int variableLength) { public LambdaExpression(int offset, int variableLength) {
super(null, variableLength); super(offset, variableLength);
setParameterList(new ParameterList());//default is empty parameterlist
}
public void setBody(Block block){
method_body = block;
}
public void setExpr(Expr expression){
Block bl = new Block();
Return returnStmt = new Return(0, 0);
returnStmt.retexpr = expression;
bl.set_Statement(returnStmt);
this.setBody(bl);
}
public void setParameterList(ParameterList params){
ParameterList lambdaParameter = new ParameterList();
for(FormalParameter fp : params){
lambdaParameter.formalparameter.add(new LambdaParameter(fp));
}
this.params = lambdaParameter;
}
@Override
public void wandleRefTypeAttributes2GenericAttributes(
Menge<Type> paralist,
Menge<GenericTypeVar> genericMethodParameters) {
Block block = this.method_body;
// 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
setType(pendantReturnType);
}
// Dann parameterlist untersuchen
for(FormalParameter fp : params){
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);
}
}
@Override
public String get_Name() {
// TODO Auto-generated method stub
return null;
} }
/**
* Spezifikation:
*
* TYPEExpr( Ass, Lambda( (x1 , . . . , xN ), expr|stmt ) ) =
* let
* AssArgs = { xi : ai | ai fresh type variables }
* (exprt : rty, ConS) = TYPEExpr( Ass ∪ AssArgs, expr )
* | (stmtt : rty, ConS) = TYPEStmt( Ass u AssArgs, stmt )
* in
* (Lambda( (x1 : a1 , . . . , xN : aN ), exprt : rty|stmtt : rty ) : a,
* ConS ∪ { (FunN<rty, a1 , . . . , aN > a) }),
* where a is a fresh type variable
*/
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
//Die Assumptions ƒÂ¼r die Parameter der LambdaExpression
TypeAssumptions ArgumentAssumptions = new TypeAssumptions(this.getParentClass().getName());
Menge<Type> paramTypes = new Menge<Type>();
for(FormalParameter param : params.formalparameter){
if(param.getType()==null)param.setType(TypePlaceholder.fresh(this));
int offset = 0;
//Jeder Parameter der LambdaExpression wird als CParaTypeAssumption der Assumption liste hinzugefügt:
ArgumentAssumptions.addAssumption(new ParameterAssumption(param));
paramTypes.add(param.getType());
}
this.setType(TypePlaceholder.fresh(this));
//ArgumentAssumptions + assumptions ergeben die Assumptions ƒÂ¼r die Statements innerhalb des Lambda-Bodys:
ret.add(method_body.TYPEStmt(ArgumentAssumptions.add(assumptions))); //Es gibt die LambdaExpression nur mit einem Block als Method Body, nicht mit einer einzelnen Expression
//Die Constraints ƒÂ¼r ParameterTypen und Ret Typ erstellen:
Type retType = method_body.getType();
if(typeIsVoid(retType)){//In diesem Fall, muss der Typ des LambdaAusdrucks FunVoid sein
this.lambdaType = new FunVoidN(paramTypes);
}else{
this.lambdaType = new FunN(retType, paramTypes);
}
ret.add(ConstraintsSet.createSingleConstraint(lambdaType.TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
return ret;
}
private boolean typeIsVoid(Type type){
return type.getName().equals(new JavaClassName("void"));
}
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions ass){
throw new TypeinferenceException("Eine LambdaExpression darf nicht als Statement verwendet werden.", this);
}
@Override
public String getTypeInformation(){
return this.getType().toString()+" :: ("+this.params.getTypeInformation()+ ") -> " +this.method_body.getTypeInformation();
}
@Override
public String toString(){
//return "LambdaExpression, Parameter: "+this.params+ ", Body: " +this.method_body;
return this.getType() + " (("+this.params+ ") -> "+this.method_body + ")";
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet){
JavaCodeResult ret = new JavaCodeResult();
ret.attach( "(").attach(this.params.printJavaCode(resultSet)).attach(")");
ret.attach( " -> ").attach( this.method_body.printJavaCode(resultSet));
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.method_body);
for(FormalParameter fp : this.params)ret.add(fp);
return ret;
}
/*
private List<LocalOrFieldVarOrClassname> crawlVariables(SyntaxTreeNode inStatements){
List<LocalOrFieldVarOrClassname> ret = new ArrayList<>();
for(SyntaxTreeNode child : inStatements.getChildren()){
ret.addAll(crawlVariables(child));
}
return ret;
}
*/
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
DHBWConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();
/*
* Anpassen der Parameter
*/
ParameterList lambdaMethodParams = new ParameterList();
//if(isStatic) //TODO: Abfrage, ob der Lambda-Ausdruck sich in einem statischen Kontext befindet
lambdaMethodParams.set_AddParameter(new FormalParameter("this", this.getParentClass().getType()));
il.append(InstructionFactory.createLoad( org.apache.bcel.generic.Type.OBJECT, 0)); //This auf den Stack legen
for(Statement s : method_body.get_Statement()){
if(s instanceof LocalOrFieldVarOrClassname){
LocalOrFieldVarOrClassname var = (LocalOrFieldVarOrClassname) s;
lambdaMethodParams.set_AddParameter(new FormalParameter(var.get_Name(),var.getType()));
//Direkt die Load instruktionen für die Parameter anhängen:
il.append(var.createLoad(cg, rs)); //Hier kann noch der cg vom Lambda-Ausdruck verwendet werden
}
}
//Das sind die zusätzlich benötigten Parameter für den invokedynamic aufruf: (hier gehört auch noch das "this" dazu)
org.apache.bcel.generic.Type[] additionalParameters = lambdaMethodParams.getBytecodeTypeList(cg, rs);
for(FormalParameter param : params){
lambdaMethodParams.set_AddParameter(param);
}
//Im Anschluss wird der this Parameter wieder von den LambdaMethodParams entfernt!
lambdaMethodParams.formalparameter.remove(0);
/*
* Generieren der Methode
*/
org.apache.bcel.generic.Type retType = method_body.getType().getBytecodeType(cg, rs);
MethodGenerator lambdaMethod = new MethodGenerator(0, retType,
lambdaMethodParams.getBytecodeTypeList(cg, rs), lambdaMethodParams.getParameterNameArray(), cg.createLambdaMethodName(),
this.getParentClass().getName().toString(), new InstructionList(), cg.getConstantPool());
lambdaMethod.setAccessFlags(Const.ACC_PRIVATE+Const.ACC_SYNTHETIC);
cg.setMethodeGenerator(lambdaMethod);
cg.addMethod(lambdaMethod.createMethod(cg, lambdaMethodParams, method_body.getType(), method_body, rs));
/*
* Generieren der Bootstrap Methode
*/
//Argumentliste für die Bootstrap Methode zusammensetzen:
ArrayList<Integer> arguments = new ArrayList<Integer>();
ConstantMethodType functionalMethodType = new ConstantMethodType(cp.addUtf8(lambdaType.getBytecodeInvokeDynamicSignature(cg, rs)));
int implMethodKind = 7; // 7 = InvokeSpecial @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5
ConstantMethodHandle implMethod = new ConstantMethodHandle(implMethodKind,cg.getConstantPool().addMethodref(lambdaMethod)); //Das zweite Argument ist der MethodRef zur LambdaMethode
arguments.add(cp.addConstant(functionalMethodType));
arguments.add(cp.addConstant(implMethod));
arguments.add(cp.addConstant(functionalMethodType));
String bootstrapSignature = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;";
int lambdaMetafactoryRefIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature);
//reference kind 6 steht für invokestatic
int lambdaMetafactoryHandle = cp.addConstant(new ConstantMethodHandle(6, lambdaMetafactoryRefIndex));
int[] argumentsArray = new int[arguments.size()];
for(int i = 0; i<arguments.size();i++){
argumentsArray[i] = arguments.get(i);
}
BootstrapMethod bMethod = new BootstrapMethod(lambdaMetafactoryHandle, argumentsArray);
/*
* Innere Klasse für das funktionieren der Bootstrap-Methode anfügen
*/
int innerClassIndex = cp.addClass("java.lang.invoke.MethodHandles$Lookup");
int innerClassName = cp.addUtf8("Lookup");
int outerClassIndex = cp.addClass("java.lang.invoke.MethodHandles");
int accessFlags = Const.ACC_FINAL + Const.ACC_STATIC + Const.ACC_PUBLIC;
InnerClass innerClassAttribute = new InnerClass(innerClassIndex, outerClassIndex, innerClassName,accessFlags);
cg.addInnerClass(innerClassAttribute);
/*
* InvokeDynamik-Instruktion anhängen
*/
String interfaceMethodName = "apply"; //Das ist ein Hack, funktioniert momentan, da nur FunN Interfaces für LambdaAusdrücke funktionieren
//String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,invokeDynamicType, bMethod));
return il;
}
} }

View File

@ -1,6 +1,11 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
/** /**
* Der FormalParameter einer LambdaExpression hat gesonderte Eigenschaften. * Der FormalParameter einer LambdaExpression hat gesonderte Eigenschaften.
@ -10,8 +15,16 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
public class LambdaParameter extends FormalParameter { public class LambdaParameter extends FormalParameter {
public LambdaParameter(FormalParameter fp) { public LambdaParameter(FormalParameter fp) {
super(null,null,0); super(fp.getDeclId());
this.setType(fp.getType());
this.parent = fp.getParent();
this.inferencelog = fp.inferencelog;
}
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return null;//Ein LambdaParameter darf keine Typen einsetzen.
} }
} }

View File

@ -3,9 +3,7 @@ package de.dhbwstuttgart.syntaxtree.statement;
// ino.end // ino.end
import de.dhbwstuttgart.syntaxtree.type.RefType; // ino.class.Literal.25490.declaration
// ino.class.Literal.25490.declaration
public abstract class Literal extends Expr public abstract class Literal extends Expr
// ino.end // ino.end
// ino.class.Literal.25490.body // ino.class.Literal.25490.body
@ -18,10 +16,6 @@ public abstract class Literal extends Expr
// ino.attribute.primitiveFlag.29399.declaration // ino.attribute.primitiveFlag.29399.declaration
private boolean primitiveFlag=true; private boolean primitiveFlag=true;
public Literal(RefType o, int i) {
super(null, i);
}
// ino.end // ino.end
// ino.method.setPrimitiveFlag.29402.definition // ino.method.setPrimitiveFlag.29402.definition
@ -40,5 +34,16 @@ public abstract class Literal extends Expr
return(this.primitiveFlag); return(this.primitiveFlag);
} }
// ino.end // ino.end
// ino.method.Literal.25494.definition
public Literal(int offset,int variableLength)
// ino.end
// ino.method.Literal.25494.body
{
super(offset,variableLength);
}
// ino.end
} }
// ino.end // ino.end

View File

@ -12,7 +12,27 @@ import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LocalVariableInstruction; import org.apache.bcel.generic.LocalVariableInstruction;
import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.MethodGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
@ -22,6 +42,9 @@ public class LocalOrFieldVarOrClassname extends Expr
// ino.class.LocalOrFieldVar.25503.body // ino.class.LocalOrFieldVar.25503.body
{ {
// ino.attribute.parserlog.25507.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
private boolean isFieldAccess = false; private boolean isFieldAccess = false;
private boolean isClassAccess = false; private boolean isClassAccess = false;
@ -30,7 +53,7 @@ public class LocalOrFieldVarOrClassname extends Expr
// ino.end // ino.end
// ino.method.LocalOrFieldVar.25510.body // ino.method.LocalOrFieldVar.25510.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
@ -39,11 +62,120 @@ public class LocalOrFieldVarOrClassname extends Expr
// ino.end // ino.end
// ino.method.LocalOrFieldVar.25513.body // ino.method.LocalOrFieldVar.25513.body
{ {
super(null,n.length()); super(offset,n.length());
usedid = new UsedId(offset);
usedid.set_Name(n);
} }
// ino.end
// ino.end // ino.method.set_UsedId.25519.definition
public void set_UsedId(UsedId u)
// ino.end
// ino.method.set_UsedId.25519.body
{
this.usedid=u;
}
// ino.end
// ino.method.get_Name.25522.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25522.body
{
return usedid.get_Name_1Element();
}
// ino.end
// ino.method.toString.25534.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25534.definition
public String toString()
// ino.end
// ino.method.toString.25534.body
{
if(getType()==null)return usedid.toString();
return usedid.toString() + ": " + getType().toString();
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25537.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25537.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
//gibt es eine Assumption ¼r den die LocalOrFieldVar-Variablen, dann folgendes ausführen:
Type thisTypeAssumption = assumptions.getVarType(this.get_Name(), this.getParentClass());
if(thisTypeAssumption == null){//Es ist keine Variable oder Feld
//Testen ob es ein Klassenname ist:
ClassAssumption cAss = assumptions.getClass(this.get_Name());
if(cAss == null)throw new TypeinferenceException("Weder eine Variable noch eine Klasse "+this.get_Name()+" ist in den Assumptions nicht vorhanden",this);
thisTypeAssumption = cAss.getAssumedClass().getType();
this.set_Type(thisTypeAssumption);
this.isClassAccess = true;
}else{
Type thisType = thisTypeAssumption.checkTYPE(assumptions, this);
this.setType(thisType);
//ret.add(new Constraint(thisTypeAssumption, this.getTypeVariable()));
//Rausfinden, ob es Feld oder Locale Variable ist:
for(FieldAssumption fAss : assumptions.getFieldVars(this.get_Name())){
if(this.getParentClass().equals(fAss.getParentClass()))this.isFieldAccess = true;
};
}
return ret;
}
public String getTypeInformation(){
return this.getType()+" "+this.get_Name();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult(this.get_Name());
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
InstructionList il = new InstructionList();
if(this.isFieldAccess){
il.append(new This(this).genByteCode(cg, rs));
il.append(cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(), this.get_Name(), this.getType().getBytecodeType(cg, rs), Constants.GETFIELD));
}else{
il.append(createLoad(cg, rs));
}
return il;
}
public LocalVariableInstruction createLoad(ClassGenerator cg, TypeinferenceResultSet rs){
Type type = this.getType();
org.apache.bcel.generic.Type byteCodeType = type.getBytecodeType(cg, rs);
String name = this.get_Name();
return cg.getMethodGenerator().createLoad(byteCodeType, name);
}
} }
// ino.end // ino.end

View File

@ -8,15 +8,35 @@ import java.util.Hashtable;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.ClassHelper;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.LocalVarAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
// ino.class.LocalVarDecl.25540.declaration // ino.class.LocalVarDecl.25540.declaration
public class LocalVarDecl extends Statement public class LocalVarDecl extends Statement implements TypeInsertable
// ino.end // ino.end
// ino.class.LocalVarDecl.25540.body // ino.class.LocalVarDecl.25540.body
{ {
@ -25,12 +45,336 @@ public class LocalVarDecl extends Statement
// ino.end // ino.end
// ino.method.LocalVarDecl.25545.body // ino.method.LocalVarDecl.25545.body
{ {
super(null,variableLength); super(offset,variableLength);
}
// ino.end
// ino.attribute.declid.25548.declaration
private Menge<DeclId> declid = new Menge<DeclId>();
// ino.end
// ino.attribute.paralist.25554.declaration
private Menge paralist = null;
// ino.end
// ino.attribute.parahash.25557.declaration
private Hashtable<String,Type> parahash = null;
// ino.end
// ino.attribute.inferencelog.25560.declaration
protected static Logger inferencelog = Logger.getLogger("inference");
// ino.end
// ino.attribute.parserlog.25563.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.attribute.block.25566.declaration
public Block block;
// ino.end
// ino.method.set_DeclId.25575.definition
public void set_DeclId(DeclId did)
// ino.end
// ino.method.set_DeclId.25575.body
{
this.declid.addElement(did);
} }
// ino.end // ino.end
public Block block; // ino.method.get_Name.25578.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25578.body
{
DeclId hilf;
hilf=declid.elementAt(0);
return hilf.get_Name();
}
// ino.end
// ino.method.set_ParaList.25581.definition
public void set_ParaList(Menge pl)
// ino.end
// ino.method.set_ParaList.25581.body
{
this.paralist = pl;
}
// ino.end
/*
// ino.method.check_anz.25590.definition
public void check_anz(Type type, Menge paralist, Menge<Class> classlist)
throws SCStatementException
// ino.end
// ino.method.check_anz.25590.body
{
boolean flag = false;
for(Enumeration<Class> e2 = classlist.elements();e2.hasMoreElements();){
Class c = e2.nextElement();
// System.out.println("vergleiche "+type.get_Type_()+" mit "+c.getName());
if(c.getName().equals(type.getName())){
// System.out.println("if(c.getName().equals(type.get_Type())){");
if(c.get_ParaList().size()>0 && paralist!=null){
parserlog.debug("Type "+type.getName()+" in classlist gefunden!");
parserlog.debug("Anzahl der localvar.paralist:"+ paralist.size()+" class.paralist: (soll) "+c.get_ParaList().size());
if(paralist.size()==c.get_ParaList().size()){
for(Enumeration e3=paralist.elements();e3.hasMoreElements();){
Type t = (Type)e3.nextElement();
parserlog.debug("Type "+t.getName()+" wird gerade untersucht");
try
{
if ( t instanceof RefType )
{
check_anz(t, ((RefType)t).get_ParaList(),classlist);
}
}
catch(SCStatementException ex)
{
throw ex;
}
}
flag = true;
parserlog.debug("flag gesetzt");
break;
}
else{
SCStatementException ex = new SCStatementException();
SCExcept e = new SCExcept();
e.set_error("Klasse "+c.getName()+" ist falsch parametrisiert!");
e.set_function("complete_parahashtable() --> check_anz()");
e.set_statement(type.getName().toString());
ex.addException(e);
throw ex;
}
}
else if(c.get_ParaList().size()==0 && paralist!=null){
SCStatementException ex = new SCStatementException();
SCExcept e = new SCExcept();
e.set_error("Klasse "+c.getName()+" ist nicht parametrisierbar!");
e.set_function("complete_parahashtable() --> check_anz()");
e.set_statement(type.getName().toString());
ex.addException(e);
throw ex;
}
else if(paralist==null && c.get_ParaList().size()>0){
parserlog.debug(paralist.toString());
parserlog.debug(c.getName()+" "+c.get_ParaList().size());
SCStatementException ex = new SCStatementException();
SCExcept e = new SCExcept();
e.set_error("Klasse "+c.getName()+" �berhaupt garnicht parametrisiert!");
e.set_function("complete_parahashtable() --> check_anz()");
e.set_statement(type.getName().toString());
ex.addException(e);
throw ex;
}
else{
flag = true;
parserlog.debug(type.getName()+" nicht parametrisierbar");
break;
}
}
}
if(!flag)
{
SCStatementException ex = new SCStatementException();
SCExcept e = new SCExcept();
if ( type instanceof RefType )
{
e.set_error("Type " + type.getName()+ " falsche Parameter-Anzahl " + ((RefType)type).get_ParaList().size());
}
e.set_function("complete_parahashtable() --> check_anz()");
e.set_statement(type.getName().toString());
ex.addException(e);
throw ex;
}
}
// ino.end
*/
public Menge<DeclId> getDeclidMenge()
// ino.end
// ino.method.getDeclidMenge.25596.body
{
return declid;
}
// ino.end
// ino.method.setDeclidMenge.25599.definition
public void setDeclidMenge(Menge<DeclId> declid)
// ino.end
// ino.method.setDeclidMenge.25599.body
{
this.declid = declid;
}
// ino.end // ino.end
// ino.method.getLineNumber.25602.defdescription type=javadoc
/**
* <br/>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @return
*/
// ino.end
// ino.method.getLineNumber.25602.definition
public int getLineNumber()
// ino.end
// ino.method.getLineNumber.25602.body
{
if(declid.size()<=0)
return MyCompiler.NO_LINENUMBER;
else{
return declid.elementAt(0).getLineNumber();
}
}
// ino.end
// ino.method.getOffset.25605.defdescription type=javadoc
/**
* <br/>Author: Thomas Hornberger
* @return
*/
// ino.end
// ino.method.getOffset.25605.definition
public int getOffset()
// ino.end
// ino.method.getOffset.25605.body
{
if(declid.size()<=0)
return MyCompiler.NO_LINENUMBER;
else{
return declid.elementAt(0).getOffset();
}
}
// ino.end
// ino.method.getTypeLineNumber.25611.defdescription type=javadoc
/**
* <br>Author: ¯Â¿Â½rg ¯Â¿Â½uerle
* @return
*/
// ino.end
// ino.method.getTypeLineNumber.25611.definition
public int getTypeLineNumber()
// ino.end
// ino.method.getTypeLineNumber.25611.body
{
return this.getLineNumber();
}
// ino.end
// ino.method.toString.25617.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25617.definition
public String toString()
// ino.end
// ino.method.toString.25617.body
{
if(this.getType() == null)return "no type " + declid.toString();
return this.getType().toString() + " " + declid.toString();
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25620.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25620.body
{
Type fpType=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
setType(pendantPara);
}
}
// ino.end
/**
* @author Andreas Stadelmeier, a10023
* Der Typ der Variablendeklaration wird den Assumptions angefügt.
* Bei einer Deklaration ohne Typangabe wird ein TypePlaceholder den Assumptions hinzugefügt.
*/
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
if((this.getType() instanceof RefType)){
Type replaceType = null;
replaceType = assumptions.checkType((RefType)this.getType(), this);
this.setType(replaceType);
}
assumptions.addAssumption(new LocalVarAssumption(this, this.getType())); //Bevor der Typ auf Void gesetzt wird.
//if(this.getType() == null)throw new DebugException("Parser Post Processing nicht aufgerufen");
ret.add(ConstraintsSet.createSingleConstraint(this.getType().TYPE(assumptions, this), this.getType().TYPE(assumptions, this)));
//assumptions.remove(null); // falls Variable mit diesem Namen bereits vorhanden.
this.setReturnType(new Void(this,0)); //Return typ einer Variablendeklaration ist Void
return ret;
}
@Override
public String getDescription(){
if(this.getType() == null)return "no type " + declid.toString();
if(this.getType() instanceof TypePlaceholder)return declid.toString();
return this.getType().toString() + " " + declid.toString();
}
@Override
public void parserPostProcessing(SyntaxTreeNode parent) {
super.parserPostProcessing(parent);
if(this.getType()==null || this.getType() instanceof TypePlaceholder)this.setType(TypePlaceholder.fresh(this));
}
@Override
public String getTypeInformation(){
String ret = "VarDeclaration ";
if(this.getType()!=null)ret+= this.getType().toString()+" ";
ret+=this.get_Name();
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
if(this.getType()!=null)ret.attach(getType().printJavaCode(resultSet)).attach(" ");
ret.attach(this.get_Name()+";");
return ret;}
@Override
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public String getIdentifier() {
return this.get_Name();
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
if(this.getType()!=null)ret.add(this.getType());
return ret;
}
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return new TypeInsertPoint(this, this, resultSet.getTypeEqualTo(tph),resultSet);
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
_cg.getMethodGenerator().getStoreIndex(get_Name());
return new InstructionList();
}
} }
// ino.end // ino.end

View File

@ -9,6 +9,20 @@ import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LDC2_W; import org.apache.bcel.generic.LDC2_W;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -20,6 +34,9 @@ public class LongLiteral extends Literal
// ino.attribute.Int.25451.declaration // ino.attribute.Int.25451.declaration
private long Long; private long Long;
// ino.end // ino.end
// ino.attribute.parserlog.25454.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.IntLiteral.25457.definition // ino.method.IntLiteral.25457.definition
@ -27,8 +44,10 @@ public class LongLiteral extends Literal
// ino.end // ino.end
// ino.method.IntLiteral.25457.body // ino.method.IntLiteral.25457.body
{ {
super(null,-1); super(-1,-1);
this.setType(new RefType("Long",this,this.getOffset()));
} }
// ino.end // ino.end
@ -68,6 +87,54 @@ public class LongLiteral extends Literal
{ {
return null; return null;
} }
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25484.definition
public String toString()
// ino.end
// ino.method.toString.25484.body
{
return getType().toString() + " " + Long;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25487.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
ConstantPoolGen cp = _cg.getConstantPool();
//InstructionFactory _factory = new InstructionFactory(cg, cp);
InstructionList il = new InstructionList();
cp.addLong(get_Long());
il.append(new LDC2_W(cp.getSize()-1));
return il;
}
} }
// ino.end // ino.end

View File

@ -11,9 +11,28 @@ import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
@ -24,6 +43,8 @@ public class MethodCall extends Expr
{ {
public MethodCall(Receiver receiver, String methodName, ArgumentList argumentList, int offset){ public MethodCall(Receiver receiver, String methodName, ArgumentList argumentList, int offset){
this(offset, 0); this(offset, 0);
this.set_Receiver(receiver);
this.set_Name(methodName);
this.set_ArgumentList(argumentList); this.set_ArgumentList(argumentList);
} }
@ -32,7 +53,7 @@ public class MethodCall extends Expr
// ino.end // ino.end
// ino.method.MethodCall.25627.body // ino.method.MethodCall.25627.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
@ -43,8 +64,11 @@ public class MethodCall extends Expr
private Receiver receiver; private Receiver receiver;
// ino.end // ino.end
// ino.attribute.arglist.25642.declaration // ino.attribute.arglist.25642.declaration
private ArgumentList arglist; private ArgumentList arglist=new ArgumentList();
// ino.attribute.parserlog.25663.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.set_ArgumentList.25666.definition // ino.method.set_ArgumentList.25666.definition
public void set_ArgumentList(ArgumentList al) public void set_ArgumentList(ArgumentList al)
@ -60,6 +84,7 @@ public class MethodCall extends Expr
// ino.end // ino.end
// ino.method.getArgumentList.25669.body // ino.method.getArgumentList.25669.body
{ {
if(this.arglist==null)return this.arglist = new ArgumentList();
return this.arglist; return this.arglist;
} }
// ino.end // ino.end
@ -71,7 +96,270 @@ public class MethodCall extends Expr
{ {
return receiver; return receiver;
} }
// ino.end
// ino.method.get_Name.25675.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25675.body
{
return this.usedid.name.firstElement();
}
// ino.end
public void set_Name(String name){
this.usedid = new UsedId(name, 0);
}
// ino.method.set_Receiver.25693.definition
public void set_Receiver(Receiver rec)
// ino.end
// ino.method.set_Receiver.25693.body
{
receiver=rec;
}
// ino.end
// ino.method.set_UsedId.25696.definition
public void set_UsedId(UsedId u)
// ino.end
// ino.method.set_UsedId.25696.body
{
usedid=u;
}
// ino.end
// ino.method.set_Expr_Menge.25699.definition
public void set_Expr_Menge(Menge<Expr> v)
// ino.end
// ino.method.set_Expr_Menge.25699.body
{
arglist.expr=v;
}
// ino.end
// ino.method.add_Expr.25702.definition
public void add_Expr(Expr e)
// ino.end
// ino.method.add_Expr.25702.body
{
arglist.expr.addElement(e);
}
// ino.end
// ino.method.toString.25738.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25738.definition
public String toString()
// ino.end
// ino.method.toString.25738.body
{
//return receiver/*.toString()*/ + " " + usedid.toString();
return type + " (" + this.get_Receiver() + "." + this.get_Name() +"(" + this.getArgumentList() + "))";
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25741.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25741.body
{
}
// ino.end
/**
* @author Andreas Stadelmeier, a10023
* @return der Name der Methode, welcher dieser MethodCall aufruft.
*/
public String getName(){
return this.usedid.toString();
}
/**
* @author AI10023 - Andreas Stadelmeier
*
* gliche Probleme:
* Wenn die Methode ohne Angabe eines Receivers im Quelltext steht:
* methodCall(param); -> (bedeutet:) this.methodCall(param);
* Parser glicherweise anpassen (siehe JavaParser.jay Zeile 1858 ff)
*/
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
//Hier der Ablauf ¼r einen Methodenaufruf:
ConstraintsSet ret = new ConstraintsSet();
//Der Return-Type des MEthodenaufrufs ist zunächst unbekannt:
this.setType(TypePlaceholder.fresh(this));
//Berechne die Constraints des Receivers
if(receiver == null){
receiver = new Receiver(new This(this));
}
ret.add(receiver.get_Expr().TYPEExpr(assumptions));
//Berechne die Constraints der Argumente aus der Argumentlist (also der Parameter, welche der Funktion übergeben wurden)
if(this.arglist != null)for(Expr arg : this.arglist.expr){
ret.add(arg.TYPEExpr(assumptions));
}
//Noch das Overloading-Constraint anhängen:
ret.add(overloading(assumptions));
/*
//Die Klasse für den Receiver setzen: Das ist für die Bytecodegenerierung notwendig.
ClassAssumption receiverClassAssumption = assumptions.getClassAssumptionFor(receiver.get_Expr().getType());
de.dhbwstuttgart.syntaxtree.Class receiverCl = receiverClassAssumption.getAssumedClass();
this.receiver.setClass(receiverCl);
*/
//Die Assumptions für den Receiver setzen:
this.receiver.setAssumptions(assumptions);
return ret;
}
/**
* Erstellt die Constraints ¼r den eigentlichen Methodenaufruf.
* Sucht in den Assumptions nach passenden Methoden und erstellt ein OderConstraintSet.
* @param assumptions
* @return
*/
public ConstraintsSet overloading(TypeAssumptions assumptions){
ConstraintsSet ret = new ConstraintsSet();
//ret.add(new Overloading(assumptions, this, this.getType()).generateConsstraints());
OderConstraint oCons = new OderConstraint();
Menge<MethodAssumption> methodAssumptions = assumptions.getMethodAssumptions(this.getName(), this.getArgumentList().size());
if(methodAssumptions.size()==0)throw new TypeinferenceException("Eine Methode "+this.get_Name()+" ist in den Assumptions nicht vorhanden", this);
//Alle glichen Methoden durchgehen:
for(MethodAssumption methodAssumption : methodAssumptions){
//Constraint nicht erstellen, falls ¼ckgabetyp von vorne herein nicht übereinstimmt:
if(!(this.type instanceof TypePlaceholder) && !this.type.equals(methodAssumption.getAssumedType()))break;
oCons.addConstraint(constraintsFromMethodAssumption(methodAssumption, assumptions));
}
ret.add(oCons);
return ret;
}
/**
* Spezifikation:
* overloading determines for all possible overloadings and overridings
* of a method the constraints, where constraints itself forms
* the constraints from the receiver type, the argument types, the return
* type and a given type assumption for the method. If it is a
* method from a class, which is not the actual class (this), all type
* variables are replaced by fresh type variables (fresh), as different
* instances can occur. sargs determines all type assumptions of a
* method, where the argument types are supertypes of a minimal type
* assumption.
*
* @TODO: wenn es sich um eine Methode einer anderen Klasse handelt, ¼ssen neue TPH vergeben werden und nicht die der Assumption verwendet werden.
*
* @return
*/
public UndConstraint constraintsFromMethodAssumption(MethodAssumption methodAssumption, TypeAssumptions assumptions){
UndConstraint methodConstraint = new UndConstraint();
//Ein Constraint ¼r den ReturnType der Methode...
methodConstraint.addConstraint(methodAssumption.getAssumedType().TYPE(assumptions, this), this.getType().TYPE(assumptions, this));
//Ein Constraint ¼r die Parameter der Methode...
for(int i=0; i<methodAssumption.getParaCount();i++){
//Type der Argument Expressions <. AssumedType der Parameter
Type ct1 = this.getArgumentList().argumentAt(i).getType().TYPE(assumptions, this);
Type ct2 = methodAssumption.getParameterType(i).TYPE(assumptions, this);
methodConstraint.addConstraint(ct1 , ct2);
}
//Ein Constraint ¼r den Receiver der Methode (falls vorhanden)...
if(this.get_Receiver() != null && this.get_Receiver().get_Expr() != null){
//TODO: FunN-MethodAssumption darf keine Klasse (Class) als ParentClass besitzen. Denn der Typ der Klasse steht noch nicht fest (bisher ist es immer "FunN").
methodConstraint.addConstraint(this.get_Receiver().get_Expr().getType().TYPE(assumptions, this), methodAssumption.getParentClassType().TYPE(assumptions, this));
}
return methodConstraint;
}
/**
* Spezifikation:
* TYPEStmt( Ass, stmt ) =
* let (stmt : rty, ConS) = TYPEExpr( Ass, stmt )
* in (stmt : Void, ConS)
*/
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions){
ConstraintsSet ret = this.TYPEExpr(assumptions); //TypeExpr aufrufen
this.setType(new Void(this,0)); //Typ des Statments auf Void setzen, da als alleinstehendes Statement
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
if(this.receiver != null)ret.attach( this.receiver.printJavaCode(resultSet)).attach(".");
ret .attach( this.get_Name());
ret .attach( "(" ).attach( this.getArgumentList().printJavaCode(resultSet)).attach( ")");
return ret.attach(";");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
for(Expr e : this.arglist.expr){
ret.add(e);
}
if(this.receiver!=null)ret.add(this.receiver.get_Expr());
return ret;
}
/*
@Override
public void parserPostProcessing(SyntaxTreeNode parent) {
super.parserPostProcessing(parent);
}
*/
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
InstructionList il = new InstructionList();
DHBWInstructionFactory _factory = cg.getInstructionFactory();
il.append(receiver.get_Expr().genByteCode(cg, rs));
//Herausfinden, ob eine Methode oder ein Interface aufgerufen wird:
Type receiverType = this.receiver.get_Expr().getType();
de.dhbwstuttgart.syntaxtree.Class receiverClass = this.receiver.getReceiverClass(cg, rs);
short kind = 0;
if(receiverClass.isInterface()){
kind = Const.INVOKEINTERFACE;
}else{//Ansonsten muss es eine Klasse sein:
kind = Const.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){
cg.getMethodGenerator().getStoreIndex(argument.get_Name());
argumentTypen[i] = argument.getType().getBytecodeType(cg, rs);
//Das Argument auf den Stack legen:
il.append(argument.genByteCode(cg, rs));
i++;
}
}
org.apache.bcel.generic.Type returnType = this.getType().getBytecodeType(cg, rs);
il.append(_factory.createInvoke(
receiver.get_Expr().getType().getBytecodeType(cg, rs).toString(),
//receiver.getReceiverClass(cg, rs).getBytecodeType(cg, rs).toString(),
this.get_Name(), returnType , argumentTypen, kind));
return il;
}
} }
// ino.end // ino.end

View File

@ -8,6 +8,25 @@ import java.util.Iterator;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
// ino.class.NegativeExpr.25744.declaration // ino.class.NegativeExpr.25744.declaration
@ -29,6 +48,9 @@ public class NegativeExpr extends UnaryExpr
// ino.attribute.expr.25754.declaration // ino.attribute.expr.25754.declaration
public Expr expr; public Expr expr;
// ino.end // ino.end
// ino.attribute.parserlog.25757.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.get_Name.25760.definition // ino.method.get_Name.25760.definition
public String get_Name() public String get_Name()
@ -57,5 +79,39 @@ public class NegativeExpr extends UnaryExpr
} }
// ino.end // ino.end
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25784.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25784.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -3,13 +3,24 @@ package de.dhbwstuttgart.syntaxtree.statement;
// ino.end // ino.end
// ino.module.NewArray.8641.import // ino.module.NewArray.8641.import
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -24,17 +35,110 @@ public class NewArray extends Expr
// ino.end // ino.end
// ino.method.NewArray.25791.body // ino.method.NewArray.25791.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
// ino.attribute.type.25794.declaration // ino.attribute.type.25794.declaration
private RefType type; private Type type;
// ino.end // ino.end
// ino.attribute.expr.25797.declaration // ino.attribute.expr.25797.declaration
public List<Expr> expr; public Menge<Expr> expr = new Menge<Expr>();
// ino.end
// ino.attribute.parserlog.25800.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end // ino.end
// ino.method.getType.25803.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* @return Returns the type.
*/
// ino.end
// ino.method.getType.25803.definition
public Type getType()
// ino.end
// ino.method.getType.25803.body
{
return type;
}
// ino.end
// ino.method.setType.25806.defdescription type=javadoc
/**
* Author: ¯Â¿Â½rg ¯Â¿Â½uerle<br/>
* @param type The type to set.
*/
// ino.end
// ino.method.setType.25806.definition
public void setType(Type type)
// ino.end
// ino.method.setType.25806.body
{
this.type = type;
}
// ino.end
// ino.method.get_Name.25809.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25809.body
{
return null;
}
// ino.end
/*
// ino.method.sc_check.25812.definition
public void sc_check(Menge<Class> classname, Hashtable bh, Hashtable<String, String> ch,boolean ext, Hashtable parach, Hashtable<String, Hashtable> parabh)
// ino.end
// ino.method.sc_check.25812.body
{
if(ext)
parserlog.debug(" ---NewArray---");
}
// ino.end
*/
// ino.method.wandleRefTypeAttributes2GenericAttributes.25827.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25827.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.addAll(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = new InstructionFactory(_cg, _cg.getConstantPool());
InstructionList il = new InstructionList();
il.append(expr.elementAt(0).genByteCode(_cg, rs));
il.append(_factory.createNewArray( org.apache.bcel.generic.Type.getType(getTypeName()), (short)1));
return il;
}
} }
// ino.end // ino.end

View File

@ -13,7 +13,30 @@ import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionConstants; import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
@ -28,14 +51,17 @@ public class NewClass extends Expr
// ino.end // ino.end
// ino.method.NewClass.25834.body // ino.method.NewClass.25834.body
{ {
super(null,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
// ino.attribute.arglist.25837.declaration // ino.attribute.arglist.25837.declaration
private ArgumentList arglist; private ArgumentList arglist;
private boolean isStatement = false; private boolean isStatement = false;
private List<RefType> parameterList = new ArrayList<>(); private List<Type> parameterList = new ArrayList<>();
// ino.end
// ino.attribute.parserlog.25840.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end // ino.end
@ -48,6 +74,159 @@ public class NewClass extends Expr
} }
// ino.end // ino.end
// ino.method.get_Name.25846.definition
public String get_Name()
// ino.end
// ino.method.get_Name.25846.body
{
return this.usedid.get_Name_1Element();
}
// ino.end
// ino.method.set_UsedId.25849.definition
public void set_UsedId( UsedId t)
// ino.end
// ino.method.set_UsedId.25849.body
{
this.usedid = t;
}
// ino.end
// ino.method.set_ArgumentList.25855.definition
public void set_ArgumentList(ArgumentList al)
// ino.end
// ino.method.set_ArgumentList.25855.body
{
this.arglist = al;
}
// ino.end
// ino.method.toString.25867.defdescription type=javadoc
/**
* <br/>Author: Martin Pl�micke
* @return
*/
// ino.end
// ino.method.toString.25867.definition
public String toString()
// ino.end
// ino.method.toString.25867.body
{
String ret = "NEW ";
Type thisType = getType();
if(thisType != null)ret += thisType.toString();
else ret += this.get_Name();
return ret;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25870.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25870.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
UndConstraint callConstraints = new UndConstraint();
int numArgs = 0;
if(this.arglist != null)numArgs = this.arglist.size();
ConstructorAssumption cA = assumptions.getConstructorAssumption(this.get_Name(), numArgs);
if(cA == null)throw new TypeinferenceException("Der Konstruktor "+this.get_Name()+" mit "+numArgs+" Parametern ist nicht vorhanden.", this);
for(int i=0; i<cA.getParaCount();i++){
ret.add(this.arglist.expr.elementAt(i).TYPEExpr(assumptions));
callConstraints.addConstraint( this.arglist.expr.elementAt(i).getType().TYPE(assumptions, this), cA.getParameterType(i).TYPE(assumptions, this));
}
//Die Parameterliste befindet sich in der UsedID:
for(Type param : this.usedid.get_ParaList()){
this.parameterList.add(param.TYPE(assumptions, this));
}
//Den Typ der Instruktion setzen:
RefType refTypeToCheck;
if(this.parameterList.size() == 0){
refTypeToCheck = new RefType(this.get_Name(),this,0);
}else{
refTypeToCheck = new RefType(this.get_Name(),this.parameterList,this,0);
}
Type thisT = assumptions.checkType(refTypeToCheck, (SyntaxTreeNode)this);
this.setType(thisT);
return ret;
}
/**
* Spezifikation:
* TYPEStmt( Ass, stmt ) =
* let (stmt : rty, ConS) = TYPEExpr( Ass, stmt )
* in (stmt : Void, ConS)
*/
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions assumptions){
ConstraintsSet ret = this.TYPEExpr(assumptions); //TypeExpr aufrufen
this.setType(new Void(this,0)); //Typ des Statments auf Void setzen.
this.isStatement = true;
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult("new ");
ret.attach(this.get_Name());
ret.attach("(");
if(this.arglist!=null && this.arglist.expr != null){
Iterator<Expr> it = this.arglist.expr.iterator();
while(it.hasNext()){
Expr arg = it.next();
ret.attach(arg.printJavaCode(resultSet));
if(it.hasNext())ret.attach(", ");
}
//ret = ret.substring(0, ret.length()-2);
}
ret.attach(")");
return ret;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
if(this.arglist!=null)for(Expr e : this.arglist.expr){
ret.add(e);
}
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
InstructionList il = new InstructionList();
//il.append(_cg.getInstructionFactory().createNew(get_Name()));
il.append(_cg.getInstructionFactory().createNew(this.getType().getBytecodeType(_cg, rs).toString()));
il.append(InstructionConstants.DUP);
String signature = getType().getBytecodeSignature(_cg, rs);
String description = signature.substring(1, signature.length()-1);
if(arglist!=null){
il.append(arglist.generateBytecode(_cg, rs));
il.append(_cg.getInstructionFactory().createInvoke(description, "<init>",
org.apache.bcel.generic.Type.VOID,
this.arglist.getBytecodeTypeList(_cg, rs), Constants.INVOKESPECIAL));
}else{
il.append(_cg.getInstructionFactory().createInvoke(description, "<init>",
org.apache.bcel.generic.Type.VOID,
new org.apache.bcel.generic.Type[]{}, Constants.INVOKESPECIAL));
}
if(this.isStatement){
il.append(InstructionConstants.POP);
}
return il;
}
} }
// ino.end // ino.end

View File

@ -8,9 +8,24 @@ import java.util.Iterator;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -34,6 +49,10 @@ public class NotExpr extends UnaryExpr
// ino.attribute.expr.25883.declaration // ino.attribute.expr.25883.declaration
public Expr expr; public Expr expr;
// ino.end // ino.end
// ino.attribute.parserlog.25886.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.get_Name.25892.definition // ino.method.get_Name.25892.definition
@ -72,5 +91,52 @@ public class NotExpr extends UnaryExpr
} }
// ino.end // ino.end
/*
public void if_codegen(ClassFile classfile, Code_attribute code, boolean sw) throws JVMCodeException {
if(expr instanceof NotExpr) if_codegen(classfile, code, !sw);
else {
expr.codegen(classfile, code);
not.if_codegen(classfile, code, sw);
}
}
*/
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25916.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25916.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
ConstraintsSet ret = new ConstraintsSet();
OderConstraint constraint = new OderConstraint();
constraint.addConstraint(this.getType().TYPE(assumptions, this), new RefType("Boolean",this,-1).TYPE(assumptions, this));
ret.add(constraint);
return ret;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -9,6 +9,19 @@ import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
@ -18,14 +31,17 @@ public class Null extends Literal
// ino.end // ino.end
// ino.class.Null.25919.body // ino.class.Null.25919.body
{ {
// ino.attribute.parserlog.25923.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.Null.25926.definition // ino.method.Null.25926.definition
public Null() public Null()
// ino.end // ino.end
// ino.method.Null.25926.body // ino.method.Null.25926.body
{ {
super(null,-1); super(-1,-1);
//this.setType(new Type("__NULL__",this,getOffset())); //this.setType(new Type("__NULL__",this,getOffset()));
} }
// ino.end // ino.end
@ -51,6 +67,41 @@ public class Null extends Literal
// ino.end // ino.end
*/ */
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25944.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25944.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
this.setType(TypePlaceholder.fresh(this));
return new ConstraintsSet();
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult("null");
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
return new Menge<SyntaxTreeNode>();
}
@Override
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool());
InstructionList il = new InstructionList();
il.append(InstructionConstants.ACONST_NULL);
return il;
}
} }
// ino.end // ino.end

View File

@ -7,8 +7,19 @@ import java.util.Hashtable;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -32,6 +43,9 @@ public class PositivExpr extends UnaryExpr
// ino.attribute.expr.25957.declaration // ino.attribute.expr.25957.declaration
public Expr expr; public Expr expr;
// ino.end // ino.end
// ino.attribute.parserlog.25960.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
@ -75,6 +89,39 @@ public class PositivExpr extends UnaryExpr
// ino.end // ino.end
*/ */
// ino.method.wandleRefTypeAttributes2GenericAttributes.25984.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.25984.body
{
}
// ino.end
@Override
public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) {
// TODO Auto-generated method stub
return null;
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

View File

@ -8,6 +8,18 @@ import java.util.Iterator;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionList;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
@ -24,6 +36,9 @@ public class PostDecExpr extends UnaryExpr
super(offset,variableLength); super(offset,variableLength);
} }
// ino.end // ino.end
// ino.attribute.parserlog.25997.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
@ -45,5 +60,33 @@ public class PostDecExpr extends UnaryExpr
} }
// ino.end // ino.end
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.26018.definition
public void wandleRefTypeAttributes2GenericAttributes(Menge<Type> paralist, Menge<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.26018.body
{
}
// ino.end
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
// TODO Auto-generated method stub
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
ret.add(this.expr);
return ret;
}
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) {
// TODO Bytecode
throw new NotImplementedException();
}
} }
// ino.end // ino.end

Some files were not shown because too many files have changed in this diff Show More