forked from JavaTX/JavaCompilerCore
Fix super calls
This commit is contained in:
parent
b80cc726c8
commit
f18903834e
11
resources/bytecode/javFiles/SuperCall.jav
Normal file
11
resources/bytecode/javFiles/SuperCall.jav
Normal file
@ -0,0 +1,11 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class Parent {
|
||||
public Parent(Integer x) {}
|
||||
}
|
||||
|
||||
public class SuperCall extends Parent {
|
||||
public SuperCall() {
|
||||
super(20);
|
||||
}
|
||||
}
|
@ -1382,8 +1382,8 @@ public class Codegen {
|
||||
generate(state, stmts.get(0));
|
||||
if (constructor.fieldInitializer() != null) {
|
||||
var stmts2 = constructor.fieldInitializer().statements();
|
||||
for (var i = 1; i < stmts2.size(); i++) {
|
||||
generate(state, stmts2.get(i));
|
||||
for (TargetExpression expression : stmts2) {
|
||||
generate(state, expression);
|
||||
}
|
||||
}
|
||||
for (var i = 1; i < stmts.size(); i++)
|
||||
|
@ -707,13 +707,19 @@ public class StatementGenerator {
|
||||
} else if (!Objects.isNull(expr.SUPER())) {
|
||||
// if(methodInvocationContext.Identifier() != null){
|
||||
name = expr.SUPER().getText();
|
||||
receiver = new Super(offset);
|
||||
}
|
||||
|
||||
ArgumentList argumentList = convertArguments(expr.expressionList());
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> signature = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
|
||||
signature.add(TypePlaceholder.fresh(offset)); // return type
|
||||
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), signature, offset);
|
||||
|
||||
MethodCall ret;
|
||||
if (expr.SUPER() != null) {
|
||||
ret = new SuperCall(argumentList, TypePlaceholder.fresh(offset), signature, offset);
|
||||
} else {
|
||||
ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), signature, offset);
|
||||
}
|
||||
|
||||
ret.setStatement();
|
||||
return ret;
|
||||
}
|
||||
@ -796,7 +802,7 @@ public class StatementGenerator {
|
||||
receiver = new This(offset);
|
||||
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
||||
} else if (parts[0].contentEquals("super")) {
|
||||
receiver = new Super(offset);
|
||||
receiver = new Super(TypePlaceholder.fresh(offset), offset);
|
||||
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
||||
|
@ -16,6 +16,7 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.Record;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import org.antlr.v4.runtime.CommonToken;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
@ -66,15 +67,6 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
@ -280,8 +272,8 @@ public class SyntaxTreeGenerator {
|
||||
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
||||
}
|
||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), genericClassParameters, offset);
|
||||
Constructor implicitConstructor = new Constructor(allmodifiers.get("public"), identifier, classType, new ParameterList(constructorParameters, offset), new Block(constructorStatements, offset), genericClassParameters, offset);
|
||||
Optional<Constructor> initializations = Optional.of(implicitConstructor);
|
||||
Constructor implicitConstructor = new Constructor(allmodifiers.get("public"), identifier, classType, new ParameterList(constructorParameters, offset), prepareBlock(new Block(constructorStatements, offset), superClass), genericClassParameters, offset);
|
||||
//Optional<Constructor> initializations = Optional.of(implicitConstructor);
|
||||
constructors.add(implicitConstructor);
|
||||
for (ClassBodyDeclarationContext bodyDeclaration : recordDeclaration.recordBody().classBodyDeclaration()) {
|
||||
convert(bodyDeclaration, fielddecl, constructors, methods, name, superClass, generics);
|
||||
@ -290,7 +282,7 @@ public class SyntaxTreeGenerator {
|
||||
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
|
||||
}
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||
return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
return new Record(modifiers, name, fielddecl, Optional.empty(), staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||
}
|
||||
|
||||
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
|
||||
@ -451,18 +443,24 @@ public class SyntaxTreeGenerator {
|
||||
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, bodydeclaration.getStart());
|
||||
}
|
||||
|
||||
protected static Block prepareBlock(Block constructorBlock, RefType superClass) {
|
||||
List<Statement> statements = constructorBlock.getStatements();
|
||||
if (statements.isEmpty() || !(statements.get(0) instanceof SuperCall)) {
|
||||
var signature = new ArrayList<RefTypeOrTPHOrWildcardOrGeneric>();
|
||||
signature.add(new Void(new NullToken()));
|
||||
statements.add(0, new SuperCall(superClass, signature, constructorBlock.getOffset()));
|
||||
}
|
||||
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
|
||||
return new Block(statements, constructorBlock.getOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9
|
||||
*/
|
||||
private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) {
|
||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||
Block block = new Block(new ArrayList<>(), offset);
|
||||
//
|
||||
//
|
||||
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset); // fieldInitializations
|
||||
// geloescht PL
|
||||
// 2018-11-24
|
||||
return new Constructor(Modifier.PUBLIC, className, classType, params, prepareBlock(new Block(new ArrayList<>(), offset), superClass), classGenerics, offset); // fieldInitializations // 2018-11-24
|
||||
}
|
||||
|
||||
/*
|
||||
@ -471,10 +469,7 @@ public class SyntaxTreeGenerator {
|
||||
private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
|
||||
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
|
||||
ParameterList params = new ParameterList(new ArrayList<>(), offset);
|
||||
Block block = new Block(new ArrayList<>(initializations), offset);
|
||||
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
|
||||
* fieldInitializations geloescht PL 2018-11-24
|
||||
*/);
|
||||
return new Constructor(Modifier.PUBLIC, className, classType, params, new Block(new ArrayList<>(initializations), offset), classGenerics, offset);
|
||||
}
|
||||
|
||||
private Method generateStaticConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
|
||||
@ -553,7 +548,7 @@ public class SyntaxTreeGenerator {
|
||||
block = stmtgen.convert(methodblock.block(), true);
|
||||
}
|
||||
if (name.equals(parentClass.getClassName())) {
|
||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart());
|
||||
return new Constructor(modifiers, name, retType, paramlist, prepareBlock(block, superClass), gtvDeclarations, methoddeclaration.getStart());
|
||||
} else {
|
||||
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart());
|
||||
}
|
||||
@ -582,7 +577,7 @@ public class SyntaxTreeGenerator {
|
||||
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
||||
Block block = stmtgen.convert(constructordeclaration.constructorBody, true);
|
||||
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
|
||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,25 @@
|
||||
package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
|
||||
import java.sql.Ref;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Constructor extends Method {
|
||||
|
||||
// TODO: Constructor braucht ein super-Statement
|
||||
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset /* , List<Statement> fieldInitializations geloescht PL 2018-11-24 */) {
|
||||
super(modifier, name, returnType, parameterList, /* codeInsideConstructor, */ prepareBlock(codeInsideConstructor) /* ,fieldInitializations )geloescht PL 2018-11-24 ) */, gtvDeclarations, offset);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fieldInitializations - Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren
|
||||
*/
|
||||
protected static Block prepareBlock(Block constructorBlock /* , List<Statement> fieldInitializations new ArrayList<>() geloescht PL 2018-11-24 */) {
|
||||
List<Statement> statements = constructorBlock.getStatements();
|
||||
statements.add(0, new SuperCall(null, null, constructorBlock.getOffset()));
|
||||
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
|
||||
return new Block(statements, constructorBlock.getOffset());
|
||||
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset) {
|
||||
super(modifier, name, returnType, parameterList, codeInsideConstructor, gtvDeclarations, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,6 +37,7 @@ public class MethodCall extends Statement
|
||||
this.receiver = receiver;
|
||||
this.receiverType = receiverType;
|
||||
this.signature = signature;
|
||||
if (signature == null) throw new NullPointerException();
|
||||
}
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> signatureArguments() {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||
@ -9,9 +12,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
|
||||
public class Super extends Expression
|
||||
{
|
||||
public Super(Token offset)
|
||||
public Super(RefTypeOrTPHOrWildcardOrGeneric type, Token offset)
|
||||
{
|
||||
super(null,null);
|
||||
super(type, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
@ -9,6 +10,7 @@ import org.antlr.v4.runtime.Token;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SuperCall extends MethodCall
|
||||
@ -20,7 +22,7 @@ public class SuperCall extends MethodCall
|
||||
|
||||
public SuperCall(ArgumentList argumentList, RefTypeOrTPHOrWildcardOrGeneric receiverType,
|
||||
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes, Token offset){
|
||||
super(new Void(offset), new ExpressionReceiver(new This(offset)), "<init>", argumentList, receiverType, argTypes, offset);
|
||||
super(new Void(offset), new ExpressionReceiver(new Super(receiverType, offset)), "<init>", argumentList, receiverType, argTypes, offset);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@ import de.dhbwstuttgart.syntaxtree.TypeScope;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -66,6 +67,7 @@ public class MethodAssumption extends Assumption{
|
||||
* @return
|
||||
*/
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) {
|
||||
if (receiver == null) return null;
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(GenericTypeVar gtv : receiver.getGenerics()){
|
||||
//Die Generics werden alle zu TPHs umgewandelt.
|
||||
|
@ -538,7 +538,23 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(SuperCall superCall) {
|
||||
// TODO: Für einen super-Call werden keine Constraints erzeugt bisher
|
||||
Set<Constraint<Pair>> methodConstraints = new HashSet<>();
|
||||
for (var clazz : info.getAvailableClasses()) {
|
||||
if (clazz.getClassName().equals(info.getCurrentClass().getSuperClass().getName())) {
|
||||
for (var ctor : clazz.getConstructors()) {
|
||||
var assumption = new MethodAssumption(null, new Void(new NullToken()), convertParams(ctor.getParameterList(), info), createTypeScope(clazz, ctor), ctor.isInherited);
|
||||
|
||||
GenericsResolver resolver = getResolverInstance();
|
||||
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(superCall, assumption, info, resolver);
|
||||
System.out.println(">>>");
|
||||
System.out.println(oneMethodConstraints);
|
||||
System.out.println("<<<");
|
||||
methodConstraints.addAll(oneMethodConstraints);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
constraintsSet.addOderConstraint(methodConstraints);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -558,10 +574,12 @@ public class TYPEStmt implements StatementVisitor {
|
||||
*/
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
|
||||
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));// PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
|
||||
if (receiverType != null) {
|
||||
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));// PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
|
||||
|
||||
// PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt
|
||||
extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT));
|
||||
// PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt
|
||||
extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT));
|
||||
}
|
||||
|
||||
// gegenseite Verschraenkung der beiden Mengen von Typannahmen
|
||||
methodConstraint.setExtendConstraint(extendsMethodConstraint);
|
||||
@ -578,7 +596,8 @@ public class TYPEStmt implements StatementVisitor {
|
||||
// methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
// extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
|
||||
|
||||
((TypePlaceholder) forMethod.getType()).setOrCons((byte) -1);// fuer Maximums-Bestimmung
|
||||
if (forMethod.getType() instanceof TypePlaceholder tph)
|
||||
tph.setOrCons((byte) -1);// fuer Maximums-Bestimmung
|
||||
|
||||
Set<Pair> parameterContraints = generateParameterConstraints(forMethod, assumption, info, resolver);
|
||||
|
||||
@ -625,7 +644,6 @@ public class TYPEStmt implements StatementVisitor {
|
||||
}
|
||||
|
||||
// Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
|
||||
System.out.println(foMethod.name);
|
||||
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
|
||||
return ret;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ public class TestComplete {
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Ignore("This is to complex")
|
||||
//@Ignore("This is too complex")
|
||||
public void matrixTest() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Matrix.jav");
|
||||
var matrix = classFiles.get("Matrix");
|
||||
@ -781,4 +781,11 @@ public class TestComplete {
|
||||
var hello = clazz.getDeclaredMethod("hello");
|
||||
hello.invoke(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuperCall() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SuperCall.jav");
|
||||
var clazz = classFiles.get("SuperCall");
|
||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user