forked from JavaTX/JavaCompilerCore
Anpassung zur Integration von Functional Interfaces und FunN$$-Typen
modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java modified: src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java modified: src/main/java/de/dhbwstuttgart/syntaxtree/Record.java modified: src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java modified: src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java modified: src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java modified: src/test/java/targetast/ASTToTypedTargetAST.java
This commit is contained in:
parent
df852ef36e
commit
c4ce97f20c
@ -34,11 +34,12 @@ public class FCGenerator {
|
||||
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
for(ClassOrInterface cly : availableClasses){
|
||||
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs, classLoader));
|
||||
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader);
|
||||
pairs.addAll(newPairs);
|
||||
|
||||
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
|
||||
if (isFunctionalInterface(cly)) {
|
||||
pairs.add(genImplFunType(cly));
|
||||
pairs.add(genImplFunType(cly, newPairs.get(0).TA1, gtvs));
|
||||
}
|
||||
}
|
||||
return pairs;
|
||||
@ -46,17 +47,22 @@ public class FCGenerator {
|
||||
|
||||
|
||||
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
|
||||
return (cly.isInterface() && cly.getMethods().size() == 1);
|
||||
return (cly.isInterface() && (cly.isFunctionalInterface() || cly.getMethods().size() == 1));
|
||||
}
|
||||
|
||||
private static Pair genImplFunType(ClassOrInterface cly) {
|
||||
Method m = cly.getMethods().get(0);
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> tl =
|
||||
(m.getParameterList().getFormalparalist().stream().map(p -> p.getType()).collect(Collectors.toList()));
|
||||
tl.add(m.getReturnType());
|
||||
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
|
||||
new RefType(cly.getClassName(), new NullToken()));
|
||||
// new FunN(lambdaParams),
|
||||
private static Pair genImplFunType(ClassOrInterface cly, RefTypeOrTPHOrWildcardOrGeneric fIType, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
||||
for(Method m : cly.getMethods()) {
|
||||
if (!java.lang.reflect.Modifier.isAbstract(m.modifier))
|
||||
continue;
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> tl =
|
||||
(m.getParameterList().getFormalparalist()
|
||||
.stream().map(p -> p.getType().acceptTV(new TypeExchanger(gtvs)))
|
||||
.collect(Collectors.toList()));
|
||||
tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs)));
|
||||
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
|
||||
fIType);
|
||||
}
|
||||
return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,6 +210,7 @@ public class SyntaxTreeGenerator {
|
||||
List<Method> methods = new ArrayList<>();
|
||||
List<Constructor> constructors = new ArrayList<>();
|
||||
Boolean isInterface = false;
|
||||
Boolean isFunctionalInterface = false;
|
||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||
for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) {
|
||||
@ -233,7 +234,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset));
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
|
||||
}
|
||||
|
||||
@ -408,7 +409,7 @@ public class SyntaxTreeGenerator {
|
||||
}
|
||||
|
||||
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
|
||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart());
|
||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, methods.size() == 1 ? true : false, extendedInterfaces, permittedSubtypes, ctx.getStart());
|
||||
}
|
||||
|
||||
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
||||
|
@ -28,11 +28,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
private GenericDeclarationList genericClassParameters;
|
||||
private RefType superClass;
|
||||
protected boolean isInterface;
|
||||
protected boolean isFunctionalInterface;
|
||||
private List<RefType> implementedInterfaces;
|
||||
private List<RefType> permittedSubtypes;
|
||||
private List<Constructor> constructors;
|
||||
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
|
||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
|
||||
super(offset);
|
||||
if (isInterface) {
|
||||
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
|
||||
@ -45,6 +46,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
this.genericClassParameters = genericClassParameters;
|
||||
this.superClass = superClass;
|
||||
this.isInterface = isInterface;
|
||||
this.isFunctionalInterface= isFunctionalInterface;
|
||||
this.implementedInterfaces = implementedInterfaces;
|
||||
this.permittedSubtypes = permittedSubtypes;
|
||||
this.methods = methods;
|
||||
@ -64,6 +66,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
this.genericClassParameters = cl.genericClassParameters;
|
||||
this.superClass = cl.superClass;
|
||||
this.isInterface = cl.isInterface;
|
||||
this.isFunctionalInterface= cl.isFunctionalInterface;
|
||||
this.implementedInterfaces = cl.implementedInterfaces;
|
||||
this.methods = new ArrayList<>(cl.methods);
|
||||
this.constructors = new ArrayList<>(cl.constructors);
|
||||
@ -82,6 +85,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
||||
}
|
||||
|
||||
public boolean isFunctionalInterface() {
|
||||
return this.isFunctionalInterface;
|
||||
}
|
||||
|
||||
// Gets if it is added
|
||||
public Boolean areMethodsAdded() {
|
||||
return methodAdded;
|
||||
@ -173,4 +180,5 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
||||
public String toString() {
|
||||
return this.name.toString() + this.genericClassParameters.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ import javax.swing.text.html.Option;
|
||||
public class Record extends ClassOrInterface {
|
||||
|
||||
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
|
||||
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset);
|
||||
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, new ArrayList<>(), offset);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Type;
|
||||
@ -86,7 +87,6 @@ public class ASTFactory {
|
||||
} catch (IOException e) {
|
||||
// Skip
|
||||
}
|
||||
|
||||
JavaClassName name = new JavaClassName(jreClass.getName());
|
||||
List<Method> methoden = new ArrayList<>();
|
||||
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
||||
@ -112,6 +112,12 @@ public class ASTFactory {
|
||||
}
|
||||
int modifier = jreClass.getModifiers();
|
||||
boolean isInterface = jreClass.isInterface();
|
||||
List<Annotation> aLA;
|
||||
boolean isFunctionalInterface =
|
||||
(aLA = Arrays.asList(jreClass.getAnnotations())).size() > 0 &&
|
||||
aLA.get(0) instanceof FunctionalInterface ?
|
||||
true :
|
||||
false;
|
||||
// see: https://stackoverflow.com/questions/9934774/getting-generic-parameter-from-supertype-class
|
||||
ParameterizedType parameterSuperClass = null;
|
||||
Type tempSuperClass = jreClass.getGenericSuperclass();
|
||||
@ -141,7 +147,7 @@ public class ASTFactory {
|
||||
|
||||
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||
|
||||
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||
cache.put(jreClass, cinf);
|
||||
return cinf;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import java.util.Optional;
|
||||
|
||||
public class FunNClass extends ClassOrInterface {
|
||||
public FunNClass(List<GenericRefType> funNParams) {
|
||||
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, false, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||
|
||||
}
|
||||
|
||||
|
@ -890,26 +890,39 @@ public class RuleSet implements IRuleSet{
|
||||
if(!(lhsType instanceof FunNType))
|
||||
return Optional.empty();
|
||||
|
||||
//FunN$$<...> <. FunctinalInterface wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
|
||||
//FunN$$<...> <. FunctinalInterface<...> wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
|
||||
if (rhsType instanceof ReferenceType) {
|
||||
|
||||
UnifyType typeD = pair.getRhsType();
|
||||
UnifyType typeFI = pair.getRhsType();
|
||||
|
||||
Optional<UnifyType> opt = fc.getRightHandedNoParameterType(typeD.getName());
|
||||
Optional<UnifyType> opt = fc.getRightHandedFunctionalInterfaceType(typeFI.getName());
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
// Should be eual as typeD
|
||||
UnifyType typeFunFc = opt.get();
|
||||
// The generic Version of typeFI (FI<a1, a2, a3, ... >)
|
||||
UnifyType typeDgen = opt.get();
|
||||
|
||||
// Actually greater+ because the types are ensured to have different names
|
||||
Set<UnifyType> smaller = fc.getChildren(typeDgen);
|
||||
opt = smaller.stream().filter(x -> x.getName().equals(pair.getLhsType().getName())).findAny();
|
||||
|
||||
if(!(typeFunFc instanceof FunNType))
|
||||
if(!opt.isPresent())
|
||||
return Optional.empty();
|
||||
|
||||
TypeParams typeDParams = typeFI.getTypeParams();
|
||||
TypeParams typeDgenParams = typeDgen.getTypeParams();
|
||||
|
||||
Unifier unif = Unifier.identity();
|
||||
for(int i = 0; i < typeDParams.size(); i++) {
|
||||
if (typeDgenParams.get(i) instanceof PlaceholderType)
|
||||
unif.add((PlaceholderType) typeDgenParams.get(i), typeDParams.get(i));
|
||||
else System.out.println("ERROR");
|
||||
}
|
||||
|
||||
UnifyType newRhsType = opt.get();
|
||||
|
||||
Set<UnifyPair> result = new HashSet<>();
|
||||
result.add(new UnifyPair(lhsType, newRhsType, PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
result.add(new UnifyPair(lhsType, unif.apply(newRhsType), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||
|
||||
return Optional.of(result);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public interface IFiniteClosure {
|
||||
public Set<UnifyType> smArg(FunNType type, Set<UnifyType> fBounded);
|
||||
|
||||
public Optional<UnifyType> getLeftHandedType(String typeName);
|
||||
public Optional<UnifyType> getRightHandedNoParameterType(String typeName);
|
||||
public Optional<UnifyType> getRightHandedFunctionalInterfaceType(String typeName);
|
||||
public Set<UnifyType> getAncestors(UnifyType t);
|
||||
public Set<UnifyType> getChildren(UnifyType t);
|
||||
public Set<UnifyType> getAllTypesByName(String typeName);
|
||||
|
@ -609,13 +609,13 @@ implements IFiniteClosure {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UnifyType> getRightHandedNoParameterType(String typeName) {
|
||||
public Optional<UnifyType> getRightHandedFunctionalInterfaceType(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
return Optional.empty();
|
||||
|
||||
for(UnifyPair pair : pairs)
|
||||
if(pair.getRhsType().getName().equals(typeName) && pair.getRhsType().typeParams.size() == 0)
|
||||
return Optional.of(pair.getLhsType());
|
||||
if(pair.getRhsType().getName().equals(typeName))
|
||||
return Optional.of(pair.getRhsType());
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class ASTToTypedTargetAST {
|
||||
|
||||
@Test
|
||||
public void emptyClass() {
|
||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, false, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
||||
assert emptyTargetClass.getName().equals("EmptyClass");
|
||||
|
Loading…
Reference in New Issue
Block a user