This commit is contained in:
JanUlrich 2016-10-07 14:12:18 +02:00
parent a33ce04734
commit e60e6b622c
16 changed files with 86 additions and 40 deletions

View File

@ -33,7 +33,7 @@ public class ClassGenerator extends ClassGen{
private DHBWConstantPoolGen cp;
private DHBWInstructionFactory factory;
private TypeinferenceResults tiResult;
//private TypeinferenceResults tiResult;
private int lambdaMethodeNr = 0;
private Type superClass;
@ -43,9 +43,9 @@ public class ClassGenerator extends ClassGen{
private List<String> methodsNamesAndTypes = new LinkedList<>();
private MethodGenerator methodGenerator;
public ClassGenerator(String name, Type superClass, String string, short accessflags, String[] strings, TypeinferenceResults typeinferenceResults) {
public ClassGenerator(String name, Type superClass, String string, short accessflags, String[] strings) {
super(name,superClass.get_Name(),string,accessflags,strings, new DHBWConstantPoolGen());
this.tiResult = typeinferenceResults;
//this.tiResult = typeinferenceResultSet;
this.superClass = superClass;
cp = (DHBWConstantPoolGen) super.getConstantPool();
@ -62,7 +62,7 @@ public class ClassGenerator extends ClassGen{
* 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();
@ -70,13 +70,13 @@ public class ClassGenerator extends ClassGen{
//return getNearestType((TypePlaceholder) t);
return new TypePlaceholderType((TypePlaceholder) t);
}else{
return t.getBytecodeType(this, getTypeinferenceResults().getTypeReconstructions().get(0));
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++);
}
@ -185,7 +185,7 @@ public class ClassGenerator extends ClassGen{
TypePlaceholder tph = it.next();
//ret += tph.getBytecodeMethodSignature(this);
//ret += ":";
ret += tph.getClassSignature(this, getTypeinferenceResults().getTypeReconstructions().get(0));
ret += tph.getClassSignature(this, null); //Es wird null übergeben. Die ClassSignaturen dürfen von keinem ResultSet abhängen.
}
ret += ">";
}
@ -199,11 +199,12 @@ public class ClassGenerator extends ClassGen{
public Map<String, ClassGenerator> getExtraClasses() {
return extraClasses;
}
public TypeinferenceResults getTypeinferenceResults() {
/*
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)
@ -225,4 +226,5 @@ public class ClassGenerator extends ClassGen{
return methodGenerator;
}
}

View File

@ -91,7 +91,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
if(pkgName != null)throw new NotImplementedException();
short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public
_cg = new ClassGenerator(name, this.getSuperClass(), name + ".java", constants , new String[] { }, typeinferenceResults); //letzter Parameter sind implementierte Interfaces
_cg = new ClassGenerator(name, this.getSuperClass(), name + ".java", constants , new String[] { }); //letzter Parameter sind implementierte Interfaces
_cp = _cg.getConstantPool();
_factory = new DHBWInstructionFactory(_cg, _cp);
@ -107,10 +107,11 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
}
//Zuerst die Methoden und Felder abarbeiten:
for(Method m : methods){
m.genByteCode(_cg, this);
m.genByteCode(_cg, this, typeinferenceResults);
}
InstructionList fieldInitializations = new InstructionList();
for(FieldDeclaration f : fieldDeclarations){
//Die Felder können noch nicht überladen werden. Hier ist nur die erste der Lösungen möglich:
fieldInitializations.append(f.genByteCode(_cg, typeinferenceResults.getTypeReconstructions().get(0)));
}
//Die Konstruktoren müssen die Feld initialisierungswerte beinhalten:
@ -1011,7 +1012,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
public boolean isInterface(){
return false;
}
/*
private Collection<? extends ByteCodeResult> getGenericClasses() {
Collection<ByteCodeResult> results = new Menge<>();

View File

@ -28,6 +28,7 @@ import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
@ -96,7 +97,7 @@ public class Constructor extends Method {
}
@Override
public void genByteCode(ClassGenerator cg, Class classObj) {
public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
this.genByteCode(cg, new InstructionList());
}
// super statement muss drin sein

View File

@ -190,11 +190,5 @@ public class FieldDeclaration extends Field{
il.append(putFieldInstruction );
return il;
}
/*@Override
public void genByteCode(ClassGen cg) {
// TODO Auto-generated method stub
}*/
}

View File

@ -44,6 +44,7 @@ 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.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
@ -396,8 +397,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
return super.equals(obj);
}
public void genByteCode(ClassGenerator cg, Class classObj) {
List<TypeinferenceResultSet> typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg);
public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
List<TypeinferenceResultSet> typeInterferenceResults = resultSets.getTypeReconstructions(this, cg);
DHBWInstructionFactory _factory = cg.getInstructionFactory();
for(TypeinferenceResultSet t: typeInterferenceResults){

View File

@ -1065,7 +1065,7 @@ public class SourceFile
}
/**
* Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces.
* Bytecode generieren für das resultSet
* @return
*/
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResults results) {
@ -1073,6 +1073,18 @@ public class SourceFile
for(Class cl : this.KlassenVektor){
ret.add(cl.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;
}

View File

@ -66,6 +66,11 @@ public class ASTFactory {
return generatedClass;
}
public static Class createInterface(String className, RefType type){
//Class generatedClass = new Class(className, )
return null;
}
public static Class createObjectClass() {
Class generatedClass = new Class("java.lang.Object", 0);

View File

@ -307,7 +307,7 @@ public class LambdaExpression extends Expr{
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(new org.apache.bcel.generic.ObjectType(lambdaType.get_Name()), 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

@ -160,11 +160,12 @@ public class LocalOrFieldVarOrClassname extends Expr
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));
}
il.append(createLoad(cg, rs));
return il;
}

View File

@ -4,6 +4,7 @@ package de.dhbwstuttgart.syntaxtree.statement;
// ino.module.MethodCall.8639.import
import java.util.Hashtable;
import org.apache.bcel.Const;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionFactory;
@ -333,9 +334,9 @@ public class MethodCall extends Expr
de.dhbwstuttgart.syntaxtree.Class receiverClass = this.receiver.getReceiverClass(cg, rs);
short kind = 0;
if(receiverClass.isInterface()){
kind = Constants.INVOKEINTERFACE;
kind = Const.INVOKEINTERFACE;
}else{//Ansonsten muss es eine Klasse sein:
kind = Constants.INVOKEVIRTUAL;
kind = Const.INVOKEVIRTUAL;
}
org.apache.bcel.generic.Type[] argumentTypen = org.apache.bcel.generic.Type.NO_ARGS;
@ -353,7 +354,10 @@ public class MethodCall extends Expr
}
org.apache.bcel.generic.Type returnType = this.getType().getBytecodeType(cg, rs);
il.append(_factory.createInvoke(receiver.getReceiverClass(cg, rs).getName().toString(), this.get_Name(), returnType , argumentTypen, kind));
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;
}

View File

@ -122,5 +122,6 @@ public class Receiver
public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult().attach(this.get_Expr().printJavaCode(resultSet));
}
}
// ino.end

View File

@ -579,12 +579,9 @@ public class RefType extends ObjectType implements IMatchable
@Override
public String getBytecodeSignature(ClassGenerator cg, TypeinferenceResultSet rs) {
String combinedType = getCombinedType(cg, rs);
if(!combinedType.equals(getName().toString())){
getSuperWildcardTypes();
Class generatedClass = ASTFactory.createClass(getCombinedType(cg, rs), getGenericClassType(), null, null, new SourceFile());
cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode());
}
/*
*/
String ret = new org.apache.bcel.generic.ObjectType(combinedType).getSignature();
return ret;
}
@ -611,8 +608,14 @@ public class RefType extends ObjectType implements IMatchable
}
return sb.toString();
}
return sb.append(this.getName().toString()).toString();
String ret = sb.append(this.getName().toString()).toString();
if(!ret.equals(getName().toString())){
//getSuperWildcardTypes();
Class generatedClass = ASTFactory.createClass(getCombinedType(cg, rs), getGenericClassType(), null, null, new SourceFile());
cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode());
}
return ret;
}
public GenericClassType getGenericClassType(){

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree.type;
// ino.end
// ino.module.Type.8677.import
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
@ -328,5 +329,15 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset
public String getClassSignature(ClassGenerator cg, TypeinferenceResultSet rs){
return this.getBytecodeSignature(cg, rs);
}
/**
* Wird beim Bytecode gebraucht.
* Einige Klassen werden vom Compiler als gegeben angenommen,
* obwohl sie sich nicht in der Java Standard Library befinden.
* Diese müssen beim generieren von Bytecode als zusätzliche Klassen generiert werden.
*
* @return - Eine Liste der Klassen, welche bei Verwendung dieses Typs zusätzlich gebraucht werden.
*/
//public abstract List<de.dhbwstuttgart.syntaxtree.Class> isClassFromJavaX();
}
// ino.end

View File

@ -18,4 +18,4 @@ public class IdTest extends SourceFileBytecodeTest{
Object obj = cls.newInstance();
assertTrue(true);
}
}
}

View File

@ -41,12 +41,12 @@ public class SingleClassTester {
for(ByteCodeResult result: bytecode){
JavaClass javaClass = result.getByteCode().getJavaClass();
javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class"));
/*
for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){
JavaClass jc = cg.getJavaClass();
jc.dump(new File(outputDirectory+jc.getClassName()+".class"));
}
*/
Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN);
}

View File

@ -4,6 +4,8 @@ import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@ -60,4 +62,13 @@ public abstract class SourceFileBytecodeTest extends TestCase{
return new URLClassLoader(urls);
}
protected void testMethod(String methodName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class testClass = getClassToTest();
for(Method m : testClass.getMethods()){
if(m.getName().equals(methodName)){
m.invoke(testClass, new Object[0]);
}
}
}
}