Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ab87b3e8d | ||
|
|
8aa5e65d15 | ||
|
|
ee295d876a | ||
|
|
075be2939f | ||
|
|
8c0d0c6b47 | ||
|
|
9035633568 | ||
|
|
ea3ce98530 | ||
|
|
bcd0c28038 | ||
|
|
9657ef5691 | ||
|
|
88db5f9eb7 | ||
|
|
8c5228f8c5 | ||
|
|
3a9a2576a2 | ||
|
|
5dccbffebd | ||
|
|
76f2048797 | ||
|
|
a1195b689d | ||
|
|
3cd61778d6 | ||
|
|
021d3e1b27 | ||
|
|
c90f01d5db | ||
|
|
8b3b018ea9 | ||
|
|
210adaa493 |
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
import Pair;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class Kombinatoren_After {
|
||||||
|
|
||||||
|
|
||||||
|
after (fst, snd) { //System.out.println("after2");
|
||||||
|
|
||||||
|
return () -> Stream.of(
|
||||||
|
toks -> {
|
||||||
|
return fst.apply().flatMap(x ->
|
||||||
|
x.apply(toks).flatMap(p1 ->
|
||||||
|
snd.apply().flatMap(y -> y.apply(p1.snd()).map(p2 ->
|
||||||
|
new Pair<>(new Pair<>(p1.fst(), p2.fst()), p2.snd()))))); } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
import Pair;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class Kombinatoren_After_Lazy {
|
||||||
|
|
||||||
|
|
||||||
|
afterP (fst, snd) {
|
||||||
|
return toks -> {
|
||||||
|
return fst.apply(toks).flatMap(p1 ->
|
||||||
|
snd.apply(p1.snd()).map(p2 ->
|
||||||
|
new Pair<>(new Pair<>(p1.fst(), p2.fst()), p2.snd())));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
import Pair;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class Kombinatoren_Or {
|
||||||
|
|
||||||
|
|
||||||
|
orP (p1, p2) {
|
||||||
|
return ()-> Stream.concat(p1.apply(), p2.apply());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
after (fst, snd) { //System.out.println("after2");
|
||||||
|
|
||||||
|
return () -> Stream.of(
|
||||||
|
toks -> {
|
||||||
|
return fst.apply().flatMap(x ->
|
||||||
|
x.apply(toks).flatMap(p1 ->
|
||||||
|
snd.apply().flatMap(y -> y.apply(p1.snd()).map(p2 ->
|
||||||
|
new Pair<>(new Pair<>(p1.fst(), p2.fst()), p2.snd()))))); } );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trans (p, f) {
|
||||||
|
return () -> p.apply().map(x -> (toks -> x.apply(toks).map(pr -> new Pair<>(f.apply(pr.fst()), pr.snd() ) ) ) );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
//import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.System;
|
||||||
|
|
||||||
|
//import java.lang.String;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import Pair;
|
||||||
|
import Kombinatoren_failure;
|
||||||
|
|
||||||
|
public class Kombinatoren_Satisfy {
|
||||||
|
|
||||||
|
kb = new Kombinatoren_failure();
|
||||||
|
|
||||||
|
satisfy(cond) {
|
||||||
|
// return () -> Stream.of (newToks -> new Kombinatoren_failure().failure().apply().map(x -> x.apply(newToks)));
|
||||||
|
//}
|
||||||
|
return () -> Stream.of (toks -> {
|
||||||
|
if(toks.isEmpty()) {
|
||||||
|
return new ArrayList<>().stream();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fst = toks.getFirst();
|
||||||
|
if (cond.apply(fst))
|
||||||
|
{
|
||||||
|
//var newToks = List.copyOf(toks.subList(1, toks.size()));
|
||||||
|
var newToks = new ArrayList<>(toks);
|
||||||
|
return newToks.removeFirst();
|
||||||
|
kb.getContent(
|
||||||
|
kb.succeed(fst).apply().map(x -> x.apply(newToks))
|
||||||
|
);
|
||||||
|
// ;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/* () -> Stream.of (toks -> {
|
||||||
|
//System.out.println(toks);
|
||||||
|
if(toks.isEmpty())
|
||||||
|
{
|
||||||
|
return new ArrayList<>().stream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fst = toks.getFirst();
|
||||||
|
if (cond.apply(fst))
|
||||||
|
{
|
||||||
|
var newToks = List.copyOf(toks.subList(1, toks.size()));
|
||||||
|
//System.out.println("satisfy ok " + fst.toString());
|
||||||
|
//return get(succeed(fst).apply().map(x -> x.apply(newToks)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//System.out.println("satisfy failure " + fst.toString());
|
||||||
|
//return get(failure().apply()).apply(toks);
|
||||||
|
}
|
||||||
|
return new ArrayList<>().stream();
|
||||||
|
} } ) ;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
import Pair;
|
||||||
|
//import java.util.function.Function;
|
||||||
|
|
||||||
|
public class Kombinatoren_Trans {
|
||||||
|
|
||||||
|
|
||||||
|
trans (p, f) {
|
||||||
|
return () -> p.apply().map(x -> (toks -> x.apply(toks).map(pr -> new Pair<>(f.apply(pr.fst()), pr.snd() ) ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import Pair;
|
||||||
|
|
||||||
|
|
||||||
|
public class Kombinatoren_failure {
|
||||||
|
public getContent(s) {
|
||||||
|
return s.toList().getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public failure() {
|
||||||
|
return () -> Stream.of(
|
||||||
|
toks -> new ArrayList<>().stream());
|
||||||
|
}
|
||||||
|
public succeed( value) {
|
||||||
|
return () -> Stream.of(toks -> {
|
||||||
|
//System.out.println("succeed");
|
||||||
|
var al = new ArrayList<>();
|
||||||
|
al.add(new Pair<>(value, toks));
|
||||||
|
//al.forEach(x -> { System.out.println(x.toString());});
|
||||||
|
return al.stream();});
|
||||||
|
}
|
||||||
|
|
||||||
|
parser(p, inp) {
|
||||||
|
return p.map(y -> y.apply(
|
||||||
|
inp.chars().mapToObj(c -> (char) c)
|
||||||
|
.collect(Collectors.toList())))
|
||||||
|
.flatMap(x -> x)
|
||||||
|
.filter(x -> x.snd().isEmpty())
|
||||||
|
.findFirst()
|
||||||
|
.get()
|
||||||
|
.fst();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
satisfy(cond) {
|
||||||
|
return newToks -> failure().apply().map(x -> x.apply(newToks));
|
||||||
|
/*
|
||||||
|
return () -> Stream.of (toks -> {
|
||||||
|
if(toks.isEmpty()) {
|
||||||
|
return new ArrayList<>().stream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fst = toks.getFirst();
|
||||||
|
if (cond.apply(fst)) {
|
||||||
|
var newToks = List.copyOf(toks.subList(1, toks.size()));
|
||||||
|
this.getContent(
|
||||||
|
succeed(fst)
|
||||||
|
.apply().map(x -> x.apply(newToks))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -1,36 +1,24 @@
|
|||||||
import java.util.Vector;
|
|
||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
import java.lang.Object;
|
import java.lang.Object;
|
||||||
|
|
||||||
class Pair<U, T> {
|
import java.util.List;
|
||||||
U a;
|
|
||||||
T b;
|
|
||||||
|
|
||||||
make(x) {
|
class Pair<T, U> {
|
||||||
var ret = new Pair<>();
|
T a;
|
||||||
ret.a = x.elementAt(0);
|
U b;
|
||||||
ret.b = x.elementAt(1);
|
|
||||||
return ret;
|
public Pair() { }
|
||||||
|
public Pair(T a, U b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T fst () {
|
||||||
eq(a, b) {
|
return a;
|
||||||
b = a;
|
|
||||||
return a == b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public U snd () {
|
||||||
compare( p) {
|
return b;
|
||||||
return eq(p.a, p.b);
|
|
||||||
//return p.a == p.b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void m(Pair<?, ?> p, Vector<?> b)
|
|
||||||
{
|
|
||||||
//this.compare(p); //1, type incorrect
|
|
||||||
this.compare(this.make(b)); //2, OK
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Pair<T, U> {
|
||||||
|
T a;
|
||||||
|
U b;
|
||||||
|
|
||||||
|
public Pair() { }
|
||||||
|
public Pair(T a, U b) {
|
||||||
|
System.out.println("Pair a; " + a + " b: " + b);
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T fst () {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public U snd () {
|
||||||
|
System.out.println("snd b: " + b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Pair<"+a.toString()+","+b.toString()+">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import java.util.stream.Stream;
|
||||||
|
//import java.util.stream.IntStream;
|
||||||
|
//import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.lang.Character;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
//import java.util.function.IntFunction;
|
||||||
|
|
||||||
|
import Pair;
|
||||||
|
|
||||||
|
|
||||||
|
public class Parser {
|
||||||
|
|
||||||
|
|
||||||
|
strToList(s) {
|
||||||
|
var al;
|
||||||
|
al = new ArrayList<>();
|
||||||
|
var i = 0;
|
||||||
|
while (i < s.length()) {
|
||||||
|
al.add(s.charAt(i));
|
||||||
|
i=i+1;
|
||||||
|
}
|
||||||
|
return al;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
parser(p, inp) {
|
||||||
|
return p.map(y -> y.apply(
|
||||||
|
strToList(inp)//chars().mapToObj(c -> (Character) c)
|
||||||
|
//.toList()
|
||||||
|
))
|
||||||
|
|
||||||
|
//.flatMap(x -> x)
|
||||||
|
|
||||||
|
//.filter(x -> x.snd().isEmpty())
|
||||||
|
;
|
||||||
|
/*
|
||||||
|
.findFirst()
|
||||||
|
.get()
|
||||||
|
.fst()
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
satisfy(cond) {
|
||||||
|
return newToks -> failure().apply().map(x -> x.apply(newToks));
|
||||||
|
/*
|
||||||
|
return () -> Stream.of (toks -> {
|
||||||
|
if(toks.isEmpty()) {
|
||||||
|
return new ArrayList<>().stream();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fst = toks.getFirst();
|
||||||
|
if (cond.apply(fst)) {
|
||||||
|
var newToks = List.copyOf(toks.subList(1, toks.size()));
|
||||||
|
this.getContent(
|
||||||
|
succeed(fst)
|
||||||
|
.apply().map(x -> x.apply(newToks))
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import java.lang.System;
|
import java.lang.System;
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
public class HelloWorld {
|
public class HelloWorld {
|
||||||
public static hello() {
|
public static hello() {
|
||||||
System.out.println("Hello World!");
|
System.out.println((Object)"Hello World!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
|
public interface Base {
|
||||||
|
Object value();
|
||||||
|
}
|
||||||
|
public record R(Integer a) implements Base {
|
||||||
|
public Object value() { return this.a; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PatternMatchingCaptures {
|
||||||
|
public test1(Base R(a)@r) {
|
||||||
|
return r.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public test2(Base R(a)) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public test3(R(a)@r) {
|
||||||
|
return r.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public test4(R(a)) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public test5(R r) {
|
||||||
|
return r.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public test6(r) {
|
||||||
|
return r.a;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -658,7 +658,7 @@ primaryPattern
|
|||||||
;
|
;
|
||||||
|
|
||||||
recordPattern
|
recordPattern
|
||||||
: typeType recordStructurePattern identifier?
|
: type=typeType? ctor=typeType recordStructurePattern ('@' identifier)?
|
||||||
//| recordStructurePattern identifier?
|
//| recordStructurePattern identifier?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -1500,6 +1500,7 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void extractField(State state, TargetType ret, TargetType type, int i, ClassOrInterface clazz) {
|
private void extractField(State state, TargetType ret, TargetType type, int i, ClassOrInterface clazz) {
|
||||||
|
state.mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
||||||
if (i >= clazz.getFieldDecl().size())
|
if (i >= clazz.getFieldDecl().size())
|
||||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||||
var field = clazz.getFieldDecl().get(i);
|
var field = clazz.getFieldDecl().get(i);
|
||||||
@@ -1560,7 +1561,7 @@ public class Codegen {
|
|||||||
state.mv.visitVarInsn(ASTORE, local.index);
|
state.mv.visitVarInsn(ASTORE, local.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
var clazz = findClass(new JavaClassName(cp.ctor().name()));
|
||||||
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
||||||
// TODO Check if class is a Record
|
// TODO Check if class is a Record
|
||||||
|
|
||||||
@@ -1568,7 +1569,7 @@ public class Codegen {
|
|||||||
var subPattern = cp.subPatterns().get(i);
|
var subPattern = cp.subPatterns().get(i);
|
||||||
|
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
extractField(state, null, cp.type(), i, clazz);
|
extractField(state, null, cp.ctor(), i, clazz);
|
||||||
|
|
||||||
if (subPattern.type() instanceof TargetRefType || subPattern.type() instanceof TargetExtendsWildcard) {
|
if (subPattern.type() instanceof TargetRefType || subPattern.type() instanceof TargetExtendsWildcard) {
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
@@ -1661,7 +1662,7 @@ public class Codegen {
|
|||||||
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
|
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
|
||||||
state.mv.visitVarInsn(ALOAD, offset);
|
state.mv.visitVarInsn(ALOAD, offset);
|
||||||
|
|
||||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
var clazz = findClass(new JavaClassName(cp.ctor().name()));
|
||||||
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
||||||
|
|
||||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||||
@@ -1670,7 +1671,7 @@ public class Codegen {
|
|||||||
if (i < cp.subPatterns().size() - 1)
|
if (i < cp.subPatterns().size() - 1)
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
|
|
||||||
extractField(state, subPattern.type(), cp.type(), i, clazz);
|
extractField(state, subPattern.type(), cp.ctor(), i, clazz);
|
||||||
if (subPattern.type() instanceof TargetRefType)
|
if (subPattern.type() instanceof TargetRefType)
|
||||||
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
||||||
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class Args {
|
|||||||
|
|
||||||
public class ConsoleInterface {
|
public class ConsoleInterface {
|
||||||
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
|
||||||
|
public static boolean writeToConsole = true;
|
||||||
public static boolean writeLogFiles = false;
|
public static boolean writeLogFiles = false;
|
||||||
public static boolean inferTogether = false;
|
public static boolean inferTogether = false;
|
||||||
public static Optional<String> unifyServerUrl = Optional.empty();
|
public static Optional<String> unifyServerUrl = Optional.empty();
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import de.dhbwstuttgart.bytecode.Codegen;
|
|||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
|
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
import de.dhbwstuttgart.exceptions.WarningsException;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
@@ -24,7 +25,6 @@ import de.dhbwstuttgart.syntaxtree.*;
|
|||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
@@ -64,6 +64,7 @@ import de.dhbwstuttgart.util.Logger;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.Record;
|
import java.lang.Record;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.sql.Array;
|
import java.sql.Array;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -103,6 +104,7 @@ public class JavaTXCompiler {
|
|||||||
public DirectoryClassLoader getClassLoader() {
|
public DirectoryClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
public final List<CompilerWarning> generatedWarnings = new ArrayList<>();
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||||
this(Collections.singletonList(sourceFile), List.of(), new File("."), ConsoleInterface.inferTogether);
|
this(Collections.singletonList(sourceFile), List.of(), new File("."), ConsoleInterface.inferTogether);
|
||||||
@@ -131,6 +133,18 @@ public class JavaTXCompiler {
|
|||||||
// INSTANCE = this;
|
// INSTANCE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void warn(CompilerWarning warning) {
|
||||||
|
this.generatedWarnings.add(warning);
|
||||||
|
}
|
||||||
|
public void checkWarnings() {
|
||||||
|
for (var warning : this.generatedWarnings) {
|
||||||
|
defaultLogger.error("[Warning] " + warning.getMessage());
|
||||||
|
}
|
||||||
|
if (!generatedWarnings.isEmpty()) {
|
||||||
|
throw new WarningsException(generatedWarnings.size() + " warnings in code, aborting!", this.generatedWarnings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<SourceFileContext> generateSources(List<File> sources) throws IOException, ClassNotFoundException {
|
private List<SourceFileContext> generateSources(List<File> sources) throws IOException, ClassNotFoundException {
|
||||||
// TODO This should maybe be moved elsewhere
|
// TODO This should maybe be moved elsewhere
|
||||||
var treeList = new ArrayList<SourceFileContext>(sources.size());
|
var treeList = new ArrayList<SourceFileContext>(sources.size());
|
||||||
@@ -425,6 +439,8 @@ public class JavaTXCompiler {
|
|||||||
return typeInference(List.of(file));
|
return typeInference(List.of(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConstraintSet<?> lastConstraints;
|
||||||
|
|
||||||
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
|
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
|
||||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
|
||||||
@@ -440,14 +456,12 @@ public class JavaTXCompiler {
|
|||||||
|
|
||||||
TYPE ty = new TYPE(definedClasses, allClasses);
|
TYPE ty = new TYPE(definedClasses, allClasses);
|
||||||
var cons = ty.getConstraints();
|
var cons = ty.getConstraints();
|
||||||
|
lastConstraints = cons;
|
||||||
|
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
|
||||||
|
|
||||||
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
Logger logger = new Logger("TypeInference");
|
||||||
if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not create directory for log files: " + logFolder);
|
|
||||||
Writer logFile = ConsoleInterface.writeLogFiles ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
|
|
||||||
Logger logger = new Logger(logFile, "TypeInference");
|
|
||||||
|
|
||||||
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
|
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
|
||||||
logger.info(finiteClosure.toString());
|
logger.info(finiteClosure.toString());
|
||||||
@@ -551,87 +565,6 @@ public class JavaTXCompiler {
|
|||||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
|
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TEMPORARY - Only for Language Server Usage
|
|
||||||
*/
|
|
||||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
|
|
||||||
var sf = sourceFiles.get(file);
|
|
||||||
if(sf == null){
|
|
||||||
sf = sourceFiles.values().stream().findFirst().get();
|
|
||||||
}
|
|
||||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
|
||||||
allClasses.addAll(sf.getClasses());
|
|
||||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
|
||||||
for (var clazz : newClasses) {
|
|
||||||
// Don't load classes that get recompiled
|
|
||||||
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
|
||||||
continue;
|
|
||||||
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
|
||||||
allClasses.add(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
|
||||||
|
|
||||||
Writer logFile = new OutputStreamWriter(new NullOutputStream());
|
|
||||||
Logger logger = new Logger(logFile, "TypeInferenceAsync");
|
|
||||||
UnifyContext context = new UnifyContext(logger, false, null, usedTasks, defaultClientPlaceholderRegistry);
|
|
||||||
try {
|
|
||||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, context.placeholderRegistry());
|
|
||||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
|
|
||||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
|
||||||
UnifyType lhs, rhs;
|
|
||||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
|
||||||
((PlaceholderType) lhs).setInnerType(true);
|
|
||||||
((PlaceholderType) rhs).setInnerType(true);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
unifyCons = unifyCons.map(distributeInnerVars);
|
|
||||||
Set<PlaceholderType> varianceTPHold;
|
|
||||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
|
||||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
|
||||||
|
|
||||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
|
||||||
|
|
||||||
if (resultmodel) {
|
|
||||||
/* UnifyResultModel Anfang */
|
|
||||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
|
||||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
|
||||||
urm.addUnifyResultListener(li);
|
|
||||||
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
|
||||||
generateBytecode(sf, li.getResults());
|
|
||||||
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
|
||||||
}
|
|
||||||
/* UnifyResultModel End */
|
|
||||||
else {
|
|
||||||
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
|
|
||||||
results.addAll(result);
|
|
||||||
|
|
||||||
results = results.stream().map(x -> {
|
|
||||||
Optional<Set<UnifyPair>> res = new RuleSet(context.placeholderRegistry()).subst(x.stream().map(y -> {
|
|
||||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
|
||||||
y.setPairOp(PairOperator.EQUALSDOT);
|
|
||||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
|
||||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
|
||||||
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
|
|
||||||
} else
|
|
||||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
}
|
|
||||||
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()));
|
|
||||||
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
||||||
*
|
*
|
||||||
@@ -718,8 +651,9 @@ public class JavaTXCompiler {
|
|||||||
var sf = sourceFiles.get(file);
|
var sf = sourceFiles.get(file);
|
||||||
if (sf.isGenerated()) continue;
|
if (sf.isGenerated()) continue;
|
||||||
var classes = generateBytecode(sf, typeinferenceResult);
|
var classes = generateBytecode(sf, typeinferenceResult);
|
||||||
|
checkWarnings();
|
||||||
sf.setGenerated();
|
sf.setGenerated();
|
||||||
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
writeClassFile(classes, file);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var treeList = generateSources(sources);
|
var treeList = generateSources(sources);
|
||||||
@@ -730,8 +664,9 @@ public class JavaTXCompiler {
|
|||||||
var sf = sourceFiles.get(file);
|
var sf = sourceFiles.get(file);
|
||||||
if (sf.isGenerated()) continue;
|
if (sf.isGenerated()) continue;
|
||||||
var classes = generateBytecode(file);
|
var classes = generateBytecode(file);
|
||||||
|
checkWarnings();
|
||||||
sf.setGenerated();
|
sf.setGenerated();
|
||||||
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
writeClassFile(classes, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -833,8 +768,8 @@ public class JavaTXCompiler {
|
|||||||
var isFunctionalInterface = false; // TODO We might actually want to generate those
|
var isFunctionalInterface = false; // TODO We might actually want to generate those
|
||||||
var implementedInterfaces = target.implementingInterfaces().stream()
|
var implementedInterfaces = target.implementingInterfaces().stream()
|
||||||
.map(t -> (RefType) toRefType(t)).toList();
|
.map(t -> (RefType) toRefType(t)).toList();
|
||||||
var permittedSubtypes = List.<RefType>of();
|
List<RefType> permittedSubtypes = null;
|
||||||
if (target instanceof TargetInterface tinf) {
|
if (target instanceof TargetInterface tinf && tinf.permittedSubtypes() != null) {
|
||||||
permittedSubtypes = tinf.permittedSubtypes().stream().map(t -> (RefType) toRefType(t)).toList();
|
permittedSubtypes = tinf.permittedSubtypes().stream().map(t -> (RefType) toRefType(t)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,6 +784,7 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
|
||||||
|
this.generatedWarnings.clear();
|
||||||
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
|
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
|
||||||
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
var generatedClasses = new HashMap<JavaClassName, byte[]>();
|
||||||
for (var clazz : sf.getClasses()) {
|
for (var clazz : sf.getClasses()) {
|
||||||
@@ -866,6 +802,10 @@ public class JavaTXCompiler {
|
|||||||
return generatedClasses;
|
return generatedClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeClassFile(Map<JavaClassName, byte[]> classFiles, File file) throws IOException {
|
||||||
|
writeClassFile(classFiles, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path, boolean preserveHierarchy) throws IOException {
|
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path, boolean preserveHierarchy) throws IOException {
|
||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
for (JavaClassName name : classFiles.keySet()) {
|
for (JavaClassName name : classFiles.keySet()) {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package de.dhbwstuttgart.exceptions;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
public class CompilerWarning extends RuntimeException {
|
||||||
|
private final Token offset;
|
||||||
|
|
||||||
|
public CompilerWarning(Token offset, String message) {
|
||||||
|
super(message);
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Token getOffset() {
|
||||||
|
return this.offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package de.dhbwstuttgart.exceptions;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WarningsException extends RuntimeException {
|
||||||
|
|
||||||
|
public final List<CompilerWarning> compilerWarnings;
|
||||||
|
|
||||||
|
public WarningsException(String message, List<CompilerWarning> warnings) {
|
||||||
|
super(message);
|
||||||
|
this.compilerWarnings = Collections.unmodifiableList(warnings);
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
-4
@@ -2,8 +2,11 @@ package de.dhbwstuttgart.languageServerInterface;
|
|||||||
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Codegen;
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
||||||
|
import de.dhbwstuttgart.exceptions.WarningsException;
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
@@ -11,6 +14,7 @@ import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
|||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||||
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -31,7 +35,7 @@ import java.util.stream.Stream;
|
|||||||
public class LanguageServerInterface {
|
public class LanguageServerInterface {
|
||||||
|
|
||||||
|
|
||||||
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||||
NameGenerator.resetTo(resetNamesTo);
|
NameGenerator.resetTo(resetNamesTo);
|
||||||
return getResultSetAndAbstractSyntax(path);
|
return getResultSetAndAbstractSyntax(path);
|
||||||
|
|
||||||
@@ -52,18 +56,32 @@ public class LanguageServerInterface {
|
|||||||
*/
|
*/
|
||||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString){
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString){
|
||||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
ConsoleInterface.logLevel = Logger.LogLevel.DEBUG;
|
||||||
|
ConsoleInterface.writeLogFiles = true;
|
||||||
|
ConsoleInterface.writeToConsole = false;
|
||||||
|
Logger.resetLogs();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var uri = new URI(pathAsString);
|
var uri = new URI(pathAsString);
|
||||||
var path = Path.of(uri);
|
var path = Path.of(uri);
|
||||||
var file = path.toFile();
|
var file = path.toFile();
|
||||||
Files.createDirectories(path.getParent().resolve("out"));
|
Files.createDirectories(path.getParent().resolve("out"));
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile(), false);
|
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile(), true);
|
||||||
compiler.generateBytecode();
|
compiler.parseAll();
|
||||||
|
|
||||||
|
List<CompilerWarning> warnings = List.of();
|
||||||
var parsedSource = compiler.sourceFiles.get(file);
|
var parsedSource = compiler.sourceFiles.get(file);
|
||||||
var tiResults = compiler.typeInference(file);
|
var tiResults = compiler.typeInference(file);
|
||||||
|
var classFiles = compiler.generateBytecode(parsedSource, tiResults);
|
||||||
|
|
||||||
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
try {
|
||||||
|
compiler.checkWarnings();
|
||||||
|
compiler.writeClassFile(classFiles, file);
|
||||||
|
} catch(WarningsException e) {
|
||||||
|
warnings = e.compilerWarnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LanguageServerTransferObject(parsedSource, "", compiler.lastConstraints, compiler.getGeneratedGenerics(), warnings);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-5
@@ -2,8 +2,10 @@ package de.dhbwstuttgart.languageServerInterface.model;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -11,21 +13,23 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class LanguageServerTransferObject {
|
public class LanguageServerTransferObject {
|
||||||
List<ResultSet> resultSets;
|
|
||||||
SourceFile Ast;
|
SourceFile Ast;
|
||||||
String printedAst;
|
String printedAst;
|
||||||
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
||||||
|
List<CompilerWarning> warnings;
|
||||||
|
ConstraintSet<?> constraints;
|
||||||
|
|
||||||
|
public LanguageServerTransferObject(SourceFile Ast, String printedAst, ConstraintSet<?> constraints, Map<SourceFile, List<GenericsResult>> generatedGenerics, List<CompilerWarning> warnings) {
|
||||||
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
|
|
||||||
this.resultSets = resultSets;
|
|
||||||
this.Ast = Ast;
|
this.Ast = Ast;
|
||||||
this.printedAst = printedAst;
|
this.printedAst = printedAst;
|
||||||
|
this.constraints = constraints;
|
||||||
this.generatedGenerics = generatedGenerics;
|
this.generatedGenerics = generatedGenerics;
|
||||||
|
this.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResultSet> getResultSets() {return resultSets;}
|
|
||||||
public SourceFile getAst() {return Ast;}
|
public SourceFile getAst() {return Ast;}
|
||||||
public String getPrintedAst() {return printedAst;}
|
public String getPrintedAst() {return printedAst;}
|
||||||
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
||||||
|
public List<CompilerWarning> getWarnings() { return warnings; };
|
||||||
|
public ConstraintSet<?> getConstraints() { return constraints; };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,9 +149,7 @@ public class StatementGenerator {
|
|||||||
if (fp.typeType() != null) {
|
if (fp.typeType() != null) {
|
||||||
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
||||||
} else {
|
} else {
|
||||||
type = methodparameters?
|
type = TypePlaceholder.fresh(fp.getStart(), 1, false);
|
||||||
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
|
||||||
: TypePlaceholder.fresh(fp.getStart(), 1, false);
|
|
||||||
}
|
}
|
||||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||||
localVars.put(paramName, type);
|
localVars.put(paramName, type);
|
||||||
@@ -484,9 +482,10 @@ public class StatementGenerator {
|
|||||||
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
||||||
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
||||||
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
|
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
|
||||||
var type = recordPatternCtx.typeType() == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
|
var type = recordPatternCtx.type == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.type, reg, generics);
|
||||||
|
var ctor = TypeGenerator.convert(recordPatternCtx.ctor, reg, generics);
|
||||||
if (text != null) localVars.put(text, type);
|
if (text != null) localVars.put(text, type);
|
||||||
var ret = new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
|
var ret = new RecordPattern(subPattern, text, type, (RefType)ctor, recordPatternCtx.getStart());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ public class SyntaxTreeGenerator {
|
|||||||
Boolean isInterface = false;
|
Boolean isInterface = false;
|
||||||
Boolean isFunctionalInterface = false;
|
Boolean isFunctionalInterface = false;
|
||||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
List<RefType> permittedSubtypes = null;
|
||||||
for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) {
|
for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) {
|
||||||
convert(clsbodydecl, fielddecl, constructors, methods, name, superClass, generics);
|
convert(clsbodydecl, fielddecl, constructors, methods, name, superClass, generics);
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ public class SyntaxTreeGenerator {
|
|||||||
if ((modifiers & 4096) != 0) {
|
if ((modifiers & 4096) != 0) {
|
||||||
if (!Objects.isNull(ctx.PERMITS())) {
|
if (!Objects.isNull(ctx.PERMITS())) {
|
||||||
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
||||||
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||||
} else {
|
} else {
|
||||||
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
||||||
throw new NotImplementedException("Invalid sealed class declaration");
|
throw new NotImplementedException("Invalid sealed class declaration");
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ import javax.swing.text.html.Option;
|
|||||||
public class Record extends ClassOrInterface {
|
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, String fileName) {
|
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, String fileName) {
|
||||||
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, new ArrayList<>(), offset, fileName);
|
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, methods.size() == 1 ? true : false, implementedInterfaces, null, offset, fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
@@ -10,21 +11,22 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|||||||
public class RecordPattern extends FormalParameter {
|
public class RecordPattern extends FormalParameter {
|
||||||
|
|
||||||
private final List<Pattern> subPattern;
|
private final List<Pattern> subPattern;
|
||||||
|
private final RefType ctor;
|
||||||
|
|
||||||
public RecordPattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric type, RefType ctor, Token offset) {
|
||||||
super(name, type, offset);
|
|
||||||
subPattern = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RecordPattern(List<Pattern> subPattern, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
|
||||||
super(name, type, offset);
|
super(name, type, offset);
|
||||||
this.subPattern = subPattern;
|
this.subPattern = subPattern;
|
||||||
|
this.ctor = ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pattern> getSubPattern() {
|
public List<Pattern> getSubPattern() {
|
||||||
return this.subPattern;
|
return this.subPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RefType getCtor() {
|
||||||
|
return ctor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ASTVisitor visitor) {
|
public void accept(ASTVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
|
|||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.exceptions.CompilerWarning;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
@@ -20,9 +21,8 @@ import de.dhbwstuttgart.target.tree.type.*;
|
|||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
|
import de.dhbwstuttgart.typeinference.unify.MartelliMontanariUnify;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import javax.swing.text.html.Option;
|
|
||||||
import java.sql.Array;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -39,11 +39,16 @@ public class ASTToTargetAST {
|
|||||||
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
||||||
|
|
||||||
public List<Generics> all;
|
public List<Generics> all;
|
||||||
//public Generics generics;
|
|
||||||
//public List<Generics> currentMethodOverloads;
|
|
||||||
|
|
||||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||||
|
final Map<Method, Set<TypePlaceholder>> usedTPHsOfMethods = new HashMap<>();
|
||||||
|
|
||||||
|
void addTPHToMethod(TypePlaceholder tph) {
|
||||||
|
var set = usedTPHsOfMethods.get(currentMethod);
|
||||||
|
set.add(tph);
|
||||||
|
}
|
||||||
|
|
||||||
private Method currentMethod;
|
private Method currentMethod;
|
||||||
|
|
||||||
public final JavaTXCompiler compiler;
|
public final JavaTXCompiler compiler;
|
||||||
@@ -209,7 +214,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<TargetType> unify(TargetType a, TargetType b) {
|
private static Optional<TargetType> unify(TargetType a, TargetType b) {
|
||||||
if (typesStrictlyEqual(a, b)) return Optional.of(a);
|
if (typesStrictlyEqual(a, b)) return Optional.ofNullable(a);
|
||||||
var unify = new MartelliMontanariUnify();
|
var unify = new MartelliMontanariUnify();
|
||||||
var ua = toUnifyType(a);
|
var ua = toUnifyType(a);
|
||||||
var unifier = unify.unify(Set.of(ua, toUnifyType(b)));
|
var unifier = unify.unify(Set.of(ua, toUnifyType(b)));
|
||||||
@@ -306,9 +311,9 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("============== INPUT ==============");
|
Target.logger.info("============== INPUT ==============");
|
||||||
for (var m : a) {
|
for (var m : a) {
|
||||||
System.out.println(m);
|
Target.logger.info(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Algorithm
|
// Algorithm
|
||||||
@@ -326,22 +331,22 @@ public class ASTToTargetAST {
|
|||||||
var u_opt = unify(m, m1);
|
var u_opt = unify(m, m1);
|
||||||
if (u_opt.isPresent()) {
|
if (u_opt.isPresent()) {
|
||||||
var u = u_opt.get();
|
var u = u_opt.get();
|
||||||
//System.out.println("Unified " + m + " AND " + m1 + "\n\t" + u);
|
//Target.logger.info("Unified " + m + " AND " + m1 + "\n\t" + u);
|
||||||
i.remove(m1);
|
i.remove(m1);
|
||||||
R.remove(m);
|
R.remove(m);
|
||||||
R.remove(m1);
|
R.remove(m1);
|
||||||
R.add(u);
|
R.add(u);
|
||||||
a.add(u);
|
a.add(u);
|
||||||
} /*else {
|
} /*else {
|
||||||
System.out.println("Couldn't unify " + m + " AND " + m1);
|
Target.logger.info("Couldn't unify " + m + " AND " + m1);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("============== OUTPUT ==============");
|
Target.logger.info("============== OUTPUT ==============");
|
||||||
for (var mg : R) {
|
for (var mg : R) {
|
||||||
System.out.println(mg.methods.size() + " " + mg);
|
Target.logger.info(mg.methods.size() + " " + mg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return R;
|
return R;
|
||||||
@@ -395,6 +400,32 @@ public class ASTToTargetAST {
|
|||||||
var bridge = generateBridgeMethod(input, genMethods);
|
var bridge = generateBridgeMethod(input, genMethods);
|
||||||
bridge.map(m1::add);
|
bridge.map(m1::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<List<TargetMethod>> pairs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < m1.size(); i++) {
|
||||||
|
for (int j = i + 1; j < m1.size(); j++) {
|
||||||
|
pairs.add(List.of(m1.get(i), m1.get(j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var duplicates = pairs.stream().filter(pair -> typesStrictlyEqual(
|
||||||
|
pair.get(0).signature().parameters().stream().map(p -> p.pattern().type()).toList(),
|
||||||
|
pair.get(1).signature().parameters().stream().map(p -> p.pattern().type()).toList())
|
||||||
|
).filter(m -> {
|
||||||
|
var a = m.get(0);
|
||||||
|
var b = m.get(1);
|
||||||
|
if (!Objects.equals(a.name(), b.name())) return false;
|
||||||
|
if (a.generics() == null || b.generics() == null) return true;
|
||||||
|
return typesAreDifferent(a.base(), a.generics(), b.generics());
|
||||||
|
}).collect(Collectors.toSet());
|
||||||
|
if (!duplicates.isEmpty()) {
|
||||||
|
for (var d : duplicates) {
|
||||||
|
var a = d.get(0);
|
||||||
|
var b = d.get(1);
|
||||||
|
compiler.warn(new CompilerWarning(a.base().getOffset(), "Duplicate Method definition " + a.name() +
|
||||||
|
" found, signature " + a.signature().getDescriptor() + " clashes with signature " + b.signature().getDescriptor()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var methods = new HashSet<>(m1).stream().toList();
|
var methods = new HashSet<>(m1).stream().toList();
|
||||||
|
|
||||||
TargetMethod staticConstructor = null;
|
TargetMethod staticConstructor = null;
|
||||||
@@ -407,7 +438,7 @@ public class ASTToTargetAST {
|
|||||||
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
else if (input.isInterface())
|
else if (input.isInterface())
|
||||||
return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces, staticConstructor,
|
return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces, staticConstructor,
|
||||||
input.getPermittedSubtypes().stream().map(t -> (TargetRefType) convert(t)).toList());
|
input.isSealed() ? input.getPermittedSubtypes().stream().map(t -> (TargetRefType) convert(t)).toList() : null);
|
||||||
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics, compiler), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics, compiler), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +458,8 @@ public class ASTToTargetAST {
|
|||||||
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
||||||
var param = input.getFormalparalist().get(i);
|
var param = input.getFormalparalist().get(i);
|
||||||
var pattern = (TargetPattern) convert(param, generics);
|
var pattern = (TargetPattern) convert(param, generics);
|
||||||
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
if (pattern instanceof TargetComplexPattern && pattern.name() == null)
|
||||||
|
pattern = pattern.withName("__var" + i);
|
||||||
res.add(new MethodParameter(pattern));
|
res.add(new MethodParameter(pattern));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@@ -460,6 +492,7 @@ public class ASTToTargetAST {
|
|||||||
List<TargetConstructor> result = new ArrayList<>();
|
List<TargetConstructor> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
this.currentMethod = input;
|
this.currentMethod = input;
|
||||||
|
this.usedTPHsOfMethods.put(input, new HashSet<>());
|
||||||
|
|
||||||
for (var s : all) {
|
for (var s : all) {
|
||||||
generics = s;
|
generics = s;
|
||||||
@@ -568,7 +601,7 @@ public class ASTToTargetAST {
|
|||||||
var body = new TargetBlock(List.of(generateCall(method, params, classType)));
|
var body = new TargetBlock(List.of(generateCall(method, params, classType)));
|
||||||
cases.add(new TargetSwitch.Case(List.of(lastPattern), body));
|
cases.add(new TargetSwitch.Case(List.of(lastPattern), body));
|
||||||
} else {
|
} else {
|
||||||
//candidates.forEach(m -> System.out.println(m.getSignature()));
|
//candidates.forEach(m -> Target.logger.info(m.getSignature()));
|
||||||
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
|
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
|
||||||
var body = new TargetBlock(List.of(caseBody));
|
var body = new TargetBlock(List.of(caseBody));
|
||||||
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
||||||
@@ -607,6 +640,7 @@ public class ASTToTargetAST {
|
|||||||
// TODO This only goes one layer deep, this is fine for records as they can't extend anything but fails for complex hierarchies
|
// TODO This only goes one layer deep, this is fine for records as they can't extend anything but fails for complex hierarchies
|
||||||
var intersection = new HashSet<>(cla.getSuperInterfaces());
|
var intersection = new HashSet<>(cla.getSuperInterfaces());
|
||||||
intersection.retainAll(clb.getSuperInterfaces());
|
intersection.retainAll(clb.getSuperInterfaces());
|
||||||
|
if (intersection.isEmpty()) return Optional.empty();
|
||||||
|
|
||||||
var intfclass = compiler.getClass(intersection.iterator().next().getName());
|
var intfclass = compiler.getClass(intersection.iterator().next().getName());
|
||||||
// We need to map the generics
|
// We need to map the generics
|
||||||
@@ -636,7 +670,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
var ta = pa.pattern().type();
|
var ta = pa.pattern().type();
|
||||||
var tb = pb.pattern().type();
|
var tb = pb.pattern().type();
|
||||||
//System.out.println(ta + " " + tb);
|
//Target.logger.info(ta + " " + tb);
|
||||||
|
|
||||||
if (Objects.equals(ta, tb)) continue;
|
if (Objects.equals(ta, tb)) continue;
|
||||||
var common = commonSealedInterface(ta, tb);
|
var common = commonSealedInterface(ta, tb);
|
||||||
@@ -727,7 +761,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var tMethod = convert(method, generics);
|
var tMethod = convert(method, generics);
|
||||||
res.add(new TargetMethod(tMethod.access(), name, tMethod.block(), tMethod.signature(), tMethod.txSignature()));
|
res.add(new TargetMethod(tMethod.access(), name, tMethod.block(), tMethod.signature(), tMethod.txSignature(), tMethod.base(), tMethod.generics()));
|
||||||
}
|
}
|
||||||
|
|
||||||
var parameters = signatureParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
var parameters = signatureParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
||||||
@@ -739,7 +773,7 @@ public class ASTToTargetAST {
|
|||||||
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType);
|
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType);
|
||||||
var block = new TargetBlock(List.of(stmt));
|
var block = new TargetBlock(List.of(stmt));
|
||||||
|
|
||||||
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, group.signature.java, group.signature.tx);
|
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, group.signature.java, group.signature.tx, firstMethod.base(), null);
|
||||||
res.add(bridgeMethod);
|
res.add(bridgeMethod);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -792,7 +826,8 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TargetMethod convert(MethodWithTphs mtph, IGenerics generics) {
|
private TargetMethod convert(MethodWithTphs mtph, IGenerics generics) {
|
||||||
return new TargetMethod(mtph.method.modifier, mtph.method.name, convert(mtph.method.block, generics), mtph.signature.java(), mtph.signature.tx());
|
this.currentMethod = mtph.method;
|
||||||
|
return new TargetMethod(mtph.method.modifier, mtph.method.name, convert(mtph.method.block, generics), mtph.signature.java(), mtph.signature.tx(), mtph.method, generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {
|
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {
|
||||||
@@ -810,9 +845,21 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean typesAreDifferent(Method m, IGenerics a, IGenerics b) {
|
||||||
|
if (m == null) return true;
|
||||||
|
var tphs = usedTPHsOfMethods.get(m);
|
||||||
|
for (var tph : tphs) {
|
||||||
|
var left = a.getTargetType(tph);
|
||||||
|
var right = b.getTargetType(tph);
|
||||||
|
if (!Objects.equals(left, right)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private Set<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
private Set<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
||||||
Set<MethodWithTphs> result = new HashSet<>();
|
Set<MethodWithTphs> result = new HashSet<>();
|
||||||
this.currentMethod = method;
|
this.currentMethod = method;
|
||||||
|
usedTPHsOfMethods.put(method, new HashSet<>());
|
||||||
|
|
||||||
List<Signature> signatures = new ArrayList<>();
|
List<Signature> signatures = new ArrayList<>();
|
||||||
for (var generics : all) {
|
for (var generics : all) {
|
||||||
@@ -836,14 +883,29 @@ public class ASTToTargetAST {
|
|||||||
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
||||||
|
|
||||||
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
||||||
//System.out.println(javaSignature.getDescriptor());
|
//Target.logger.info(javaSignature.getDescriptor());
|
||||||
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), generics.txGenerics, compiler));
|
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), generics.txGenerics, compiler));
|
||||||
|
|
||||||
signatures.add(new Signature(javaSignature, txSignature, generics));
|
signatures.add(new Signature(javaSignature, txSignature, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!signatures.isEmpty()) {
|
||||||
|
var signature = signatures.getFirst();
|
||||||
|
// We need to convert once to find out what TPHs are existing in the given method
|
||||||
|
convert(new MethodWithTphs(method, signature.generics, signature));
|
||||||
|
}
|
||||||
|
|
||||||
for (var signature : signatures) {
|
for (var signature : signatures) {
|
||||||
result.add(new MethodWithTphs(method, signature.generics, signature));
|
var mtph = new MethodWithTphs(method, signature.generics, signature);
|
||||||
|
var duplicate = result.stream().filter(m -> m.signature.java.equals(signature.java))
|
||||||
|
.filter(m -> typesAreDifferent(method, m.generics.javaGenerics, signature.generics.javaGenerics)).findFirst();
|
||||||
|
if (duplicate.isPresent()) {
|
||||||
|
var d = duplicate.get();
|
||||||
|
compiler.warn(new CompilerWarning(method.block.getOffset(), "Duplicate Method definition " + method.name +
|
||||||
|
" found, signature " + d.signature.java.getDescriptor() + " clashes with signature " + signature.java.getDescriptor()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.add(mtph);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -970,6 +1032,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, IGenerics generics) {
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, IGenerics generics) {
|
||||||
|
if (currentMethod != null && input instanceof TypePlaceholder tph) addTPHToMethod(tph);
|
||||||
return convert(input, generics, compiler);
|
return convert(input, generics, compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
|
|||||||
public abstract class GenerateGenerics implements IGenerics {
|
public abstract class GenerateGenerics implements IGenerics {
|
||||||
|
|
||||||
private final JavaTXCompiler compiler;
|
private final JavaTXCompiler compiler;
|
||||||
|
private final ResultSet constraints;
|
||||||
|
|
||||||
public class TPH {
|
public class TPH {
|
||||||
private final TypePlaceholder wrap;
|
private final TypePlaceholder wrap;
|
||||||
@@ -129,7 +130,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
final Map<Method, Set<Pair>> computedGenericsOfMethods = new HashMap<>();
|
final Map<Method, Set<Pair>> computedGenericsOfMethods = new HashMap<>();
|
||||||
final Map<ClassOrInterface, Set<Pair>> computedGenericsOfClasses = new HashMap<>();
|
final Map<ClassOrInterface, Set<Pair>> computedGenericsOfClasses = new HashMap<>();
|
||||||
|
|
||||||
final Map<Method, Set<TPH>> usedTPHsOfMethods = new HashMap<>();
|
final Map<Method, Set<TPH>> usedTPHsOfMethodSignatures = new HashMap<>();
|
||||||
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
|
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
|
||||||
|
|
||||||
final Set<PairLT> simplifiedConstraints = new HashSet<>();
|
final Set<PairLT> simplifiedConstraints = new HashSet<>();
|
||||||
@@ -138,6 +139,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
|
|
||||||
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
|
this.constraints = constraints;
|
||||||
for (var constraint : constraints.results) {
|
for (var constraint : constraints.results) {
|
||||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||||
Target.logger.info(p.left + " " + p.left.getVariance());
|
Target.logger.info(p.left + " " + p.left.getVariance());
|
||||||
@@ -583,7 +585,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
referenced.addAll(typeVariablesOfClass);
|
referenced.addAll(typeVariablesOfClass);
|
||||||
|
|
||||||
generics(owner, method, result, referenced);
|
generics(owner, method, result, referenced);
|
||||||
usedTPHsOfMethods.put(method, usedTphs);
|
usedTPHsOfMethodSignatures.put(method, usedTphs);
|
||||||
|
|
||||||
normalize(result, classGenerics, usedTphs);
|
normalize(result, classGenerics, usedTphs);
|
||||||
|
|
||||||
@@ -782,7 +784,7 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
}
|
}
|
||||||
doIterationForMethods(classOrInterface);
|
doIterationForMethods(classOrInterface);
|
||||||
for (var method : classOrInterface.getMethods()) {
|
for (var method : classOrInterface.getMethods()) {
|
||||||
var usedTPHs = usedTPHsOfMethods.get(method);
|
var usedTPHs = usedTPHsOfMethodSignatures.get(method);
|
||||||
if (usedTPHs != null)
|
if (usedTPHs != null)
|
||||||
referenced.addAll(usedTPHs);
|
referenced.addAll(usedTPHs);
|
||||||
}
|
}
|
||||||
@@ -981,6 +983,11 @@ public abstract class GenerateGenerics implements IGenerics {
|
|||||||
} while (foundInfima);
|
} while (foundInfima);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return this.constraints;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypePlaceholder getEqualType(TypePlaceholder tph) {
|
public TypePlaceholder getEqualType(TypePlaceholder tph) {
|
||||||
return this.equality.getOrDefault(tph, tph);
|
return this.equality.getOrDefault(tph, tph);
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ public class GenericsResult {
|
|||||||
this.generics = generics;
|
this.generics = generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IGenerics getGenerics() {
|
||||||
|
return this.generics;
|
||||||
|
}
|
||||||
|
|
||||||
public GenericsResultSet get(ClassOrInterface clazz) {
|
public GenericsResultSet get(ClassOrInterface clazz) {
|
||||||
var generics = this.generics.generics(clazz);
|
var generics = this.generics.generics(clazz);
|
||||||
return new GenericsResultSet(generics, this.generics);
|
return new GenericsResultSet(generics, this.generics);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
||||||
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||||
import org.antlr.v4.codegen.model.decl.ContextRuleListIndexedGetterDecl;
|
import org.antlr.v4.codegen.model.decl.ContextRuleListIndexedGetterDecl;
|
||||||
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -18,7 +20,12 @@ public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
|||||||
this.generics = generics;
|
this.generics = generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IGenerics getGenerics() {
|
||||||
|
return this.generics;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public Iterator<GenerateGenerics.Pair> iterator() {
|
public Iterator<GenerateGenerics.Pair> iterator() {
|
||||||
return backing.iterator();
|
return backing.iterator();
|
||||||
}
|
}
|
||||||
@@ -28,17 +35,8 @@ public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
|||||||
return backing.size();
|
return backing.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) {
|
public Optional<GenerateGenerics.Pair> getResultPairFor(TypePlaceholder tph) {
|
||||||
var tph2 = generics.getEqualType(tph);
|
var tph2 = generics.getEqualType(tph);
|
||||||
return this.stream().filter(pair -> {
|
return this.stream().filter(pair -> pair.left.resolve().equals(tph2)).findFirst();
|
||||||
return pair.left.resolve().equals(tph2);
|
|
||||||
}).findFirst().map(pair -> {
|
|
||||||
ResultPair<?, ?> res = null;
|
|
||||||
if (pair instanceof GenerateGenerics.PairLT lt)
|
|
||||||
res = new PairTPHsmallerTPH(lt.left.resolve(), lt.right.resolve());
|
|
||||||
else if (pair instanceof GenerateGenerics.PairEQ eq)
|
|
||||||
res = new PairTPHequalRefTypeOrWildcardType(eq.left.resolve(), eq.right);
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import de.dhbwstuttgart.syntaxtree.Method;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -19,4 +20,6 @@ public interface IGenerics {
|
|||||||
TypePlaceholder getEqualType(TypePlaceholder tph);
|
TypePlaceholder getEqualType(TypePlaceholder tph);
|
||||||
|
|
||||||
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in);
|
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in);
|
||||||
|
|
||||||
|
ResultSet getResultSet();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -57,4 +58,9 @@ public class OverlayGenerics implements IGenerics {
|
|||||||
}
|
}
|
||||||
return ASTToTargetAST.convert(in, this, converter.compiler);
|
return ASTToTargetAST.convert(in, this, converter.compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet getResultSet() {
|
||||||
|
return wrapped.getResultSet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -609,6 +609,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(RecordPattern aRecordPattern) {
|
public void visit(RecordPattern aRecordPattern) {
|
||||||
result = new TargetComplexPattern(
|
result = new TargetComplexPattern(
|
||||||
|
converter.convert(aRecordPattern.getCtor(), generics),
|
||||||
converter.convert(aRecordPattern.getType(), generics),
|
converter.convert(aRecordPattern.getType(), generics),
|
||||||
aRecordPattern.getName(),
|
aRecordPattern.getName(),
|
||||||
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x, generics)).toList()
|
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x, generics)).toList()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.dhbwstuttgart.target.tree;
|
package de.dhbwstuttgart.target.tree;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.target.generate.IGenerics;
|
||||||
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
||||||
import de.dhbwstuttgart.target.tree.expression.TargetPattern;
|
import de.dhbwstuttgart.target.tree.expression.TargetPattern;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
@@ -9,7 +11,11 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature) {
|
public record TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature, Method base, IGenerics generics) {
|
||||||
|
public TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature) {
|
||||||
|
this(access, name, block, signature, txSignature, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public record Signature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
public record Signature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||||
public String getSignature() {
|
public String getSignature() {
|
||||||
return TargetMethod.getSignature(generics, parameters, returnType);
|
return TargetMethod.getSignature(generics, parameters, returnType);
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public record TargetComplexPattern(TargetType type, String name, List<TargetPattern> subPatterns) implements TargetPattern {
|
public record TargetComplexPattern(TargetType ctor, TargetType type, String name, List<TargetPattern> subPatterns) implements TargetPattern {
|
||||||
@Override
|
@Override
|
||||||
public TargetComplexPattern withType(TargetType type) {
|
public TargetComplexPattern withType(TargetType type) {
|
||||||
return new TargetComplexPattern(type, name, subPatterns);
|
return new TargetComplexPattern(ctor, type, name, subPatterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetComplexPattern withName(String name) {
|
public TargetComplexPattern withName(String name) {
|
||||||
return new TargetComplexPattern(type, name, subPatterns);
|
return new TargetComplexPattern(ctor, type, name, subPatterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -187,14 +187,14 @@ class TypeToInsertString implements ResultSetVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(TypePlaceholder typePlaceholder) {
|
public void visit(TypePlaceholder typePlaceholder) {
|
||||||
ResultPair<?, ?> resultPair = null;
|
GenerateGenerics.Pair resultPair = null;
|
||||||
if (constraints != null)
|
if (constraints != null)
|
||||||
resultPair = constraints.getResultPairFor(typePlaceholder).orElse(null);
|
resultPair = constraints.getResultPairFor(typePlaceholder).orElse(null);
|
||||||
if (resultPair == null)
|
if (resultPair == null)
|
||||||
resultPair = classConstraints.getResultPairFor(typePlaceholder).orElse(null);
|
resultPair = classConstraints.getResultPairFor(typePlaceholder).orElse(null);
|
||||||
|
|
||||||
if (resultPair != null)
|
if (resultPair != null)
|
||||||
insert += ((TypePlaceholder)resultPair.getLeft()).getName();
|
insert += resultPair.left.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -120,10 +120,12 @@ public class TYPE {
|
|||||||
|
|
||||||
var subPatternList = recordPattern.getSubPattern();
|
var subPatternList = recordPattern.getSubPattern();
|
||||||
var resolver = new GenericsResolverSameName();
|
var resolver = new GenericsResolverSameName();
|
||||||
var refType = (RefType) recordPattern.getType();
|
var ctorType = recordPattern.getCtor();
|
||||||
|
|
||||||
|
constraintSet.addUndConstraint(new Pair(ctorType, recordPattern.getType(), PairOperator.SMALLERDOT));
|
||||||
|
|
||||||
var allClasses = blockInformation.getAvailableClasses();
|
var allClasses = blockInformation.getAvailableClasses();
|
||||||
var typename = refType.getName().getClassName();
|
var typename = ctorType.getName().getClassName();
|
||||||
|
|
||||||
ClassOrInterface allClass = allClasses.stream().filter(c -> c.getClassName().getClassName().equals(typename)).findFirst().orElseThrow();
|
ClassOrInterface allClass = allClasses.stream().filter(c -> c.getClassName().getClassName().equals(typename)).findFirst().orElseThrow();
|
||||||
|
|
||||||
@@ -136,12 +138,12 @@ public class TYPE {
|
|||||||
FieldAssumption assumption = new FieldAssumption(param.getName(), allClass, param.getType(), blockInformation.getCurrentTypeScope());
|
FieldAssumption assumption = new FieldAssumption(param.getName(), allClass, param.getType(), blockInformation.getCurrentTypeScope());
|
||||||
|
|
||||||
var fieldCons = new Pair(el.getType(), assumption.getType(resolver), PairOperator.SMALLERDOT);
|
var fieldCons = new Pair(el.getType(), assumption.getType(resolver), PairOperator.SMALLERDOT);
|
||||||
var recvCons = new Pair(refType, assumption.getReceiverType(resolver), PairOperator.EQUALSDOT);
|
var recvCons = new Pair(ctorType, assumption.getReceiverType(resolver), PairOperator.EQUALSDOT);
|
||||||
constraintSet.addUndConstraint(fieldCons);
|
constraintSet.addUndConstraint(fieldCons);
|
||||||
constraintSet.addUndConstraint(recvCons);
|
constraintSet.addUndConstraint(recvCons);
|
||||||
|
|
||||||
for (var i = 0; i < refType.getParaList().size(); i++) {
|
for (var i = 0; i < ctorType.getParaList().size(); i++) {
|
||||||
constraintSet.addUndConstraint(new Pair(refType.getParaList().get(i),
|
constraintSet.addUndConstraint(new Pair(ctorType.getParaList().get(i),
|
||||||
((RefType)assumption.getReceiverType(resolver)).getParaList().get(i),
|
((RefType)assumption.getReceiverType(resolver)).getParaList().get(i),
|
||||||
PairOperator.EQUALSDOT));
|
PairOperator.EQUALSDOT));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -736,12 +736,12 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
|
for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
|
||||||
// Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params)
|
// Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params)
|
||||||
ret.add(new Pair(foMethod.signature.get(i), assumption.getArgTypes().get(i), PairOperator.EQUALSDOT));
|
ret.add(new Pair(resolver.resolve(foMethod.signature.get(i)), resolver.resolve(assumption.getArgTypes().get(i)), PairOperator.EQUALSDOT));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
|
// Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
|
||||||
ret.add(new Pair(foMethod.signature.getLast(), assumption.getReturnType(), PairOperator.EQUALSDOT));
|
ret.add(new Pair(resolver.resolve(foMethod.signature.getLast()), resolver.resolve(assumption.getReturnType()), PairOperator.EQUALSDOT));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -755,7 +755,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
UnifyType lhsType = pair.getLhsType();
|
UnifyType lhsType = pair.getLhsType();
|
||||||
UnifyType rhsType = pair.getRhsType();
|
UnifyType rhsType = pair.getRhsType();
|
||||||
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof ExtendsType))
|
if((!(lhsType instanceof ReferenceType) && !(lhsType instanceof FunNType)) || !(rhsType instanceof ExtendsType))
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
return Optional.of(new UnifyPair(lhsType, ((ExtendsType) rhsType).getExtendedType(), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
@@ -781,7 +781,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
UnifyType lhsType = pair.getLhsType();
|
UnifyType lhsType = pair.getLhsType();
|
||||||
UnifyType rhsType = pair.getRhsType();
|
UnifyType rhsType = pair.getRhsType();
|
||||||
if(!(lhsType instanceof ReferenceType) || !(rhsType instanceof SuperType))
|
if((!(lhsType instanceof ReferenceType) && !(lhsType instanceof FunNType)) || !(rhsType instanceof SuperType))
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
return Optional.of(new UnifyPair(((SuperType) rhsType).getSuperedType(), lhsType, PairOperator.SMALLERDOTWC, pair.getSubstitution(), pair.getBasePair()));
|
||||||
@@ -904,7 +904,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
|
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
|
||||||
var retType = fiArgs.getFirst();
|
var retType = fiArgs.getFirst();
|
||||||
var lhsArgs = intf.getFunctionalInterfaceTypeArguments(lhsType);
|
var lhsArgs = intf.getFunctionalInterfaceTypeArguments(lhsType); //FALSCHRUM????
|
||||||
var lhsRet = lhsArgs.getFirst();
|
var lhsRet = lhsArgs.getFirst();
|
||||||
|
|
||||||
Set<UnifyPair> result = new HashSet<>();
|
Set<UnifyPair> result = new HashSet<>();
|
||||||
@@ -972,16 +972,66 @@ public class RuleSet implements IRuleSet{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair) {
|
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair, IFiniteClosure fc) {
|
||||||
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
if(pair.getPairOp() != PairOperator.SMALLERDOT)
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
UnifyType lhsType = pair.getLhsType();
|
UnifyType lhsType = pair.getLhsType();
|
||||||
UnifyType rhsType = pair.getRhsType();
|
UnifyType rhsType = pair.getRhsType();
|
||||||
|
|
||||||
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof FunNType))
|
if(!(rhsType instanceof FunNType))
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
|
/* muss nach angepasst werden */
|
||||||
|
//FunN$$<...> <. FunctinalInterface<...> wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
|
||||||
|
if (lhsType instanceof ReferenceType) {
|
||||||
|
UnifyType typeFI = pair.getLhsType();
|
||||||
|
|
||||||
|
Optional<UnifyType> opt = fc.getRightHandedFunctionalInterfaceType(typeFI.getName());
|
||||||
|
if(!opt.isPresent())
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
if (!(typeFI instanceof ReferenceType refType) || !(refType instanceof FunInterfaceType intf))
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
|
||||||
|
var retType = fiArgs.getFirst();
|
||||||
|
var rhsArgs = intf.getFunctionalInterfaceTypeArguments(rhsType);
|
||||||
|
var rhsRet = rhsArgs.getFirst();
|
||||||
|
|
||||||
|
Set<UnifyPair> result = new HashSet<>();
|
||||||
|
//if (retType instanceof ExtendsType) {
|
||||||
|
result.add(new UnifyPair(retType, rhsRet, PairOperator.SMALLER));
|
||||||
|
//} else if (retType instanceof SuperType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
// result.add(new UnifyPair(lhsRet, retType, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
|
||||||
|
for (var i = 1; i < fiArgs.size(); i++) {
|
||||||
|
var rh = rhsArgs.get(i);
|
||||||
|
var lh = fiArgs.get(i);
|
||||||
|
|
||||||
|
//if (rh instanceof SuperType) {
|
||||||
|
result.add(new UnifyPair(rh, lh, PairOperator.SMALLER));
|
||||||
|
//} else if (rh instanceof ExtendsType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
// result.add(new UnifyPair(lh, rh, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if(!(lhsType instanceof PlaceholderType))
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FunNType funNRhsType = (FunNType) rhsType;
|
FunNType funNRhsType = (FunNType) rhsType;
|
||||||
|
|
||||||
Set<UnifyPair> result = new HashSet<UnifyPair>();
|
Set<UnifyPair> result = new HashSet<UnifyPair>();
|
||||||
@@ -1018,6 +1068,121 @@ public class RuleSet implements IRuleSet{
|
|||||||
return Optional.of(result);
|
return Optional.of(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Set<UnifyPair>> reduceFIFunN(UnifyPair pair, IFiniteClosure fc) {
|
||||||
|
if(pair.getPairOp() != PairOperator.EQUALSDOT)
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
UnifyType lhsType = pair.getLhsType();
|
||||||
|
UnifyType rhsType = pair.getRhsType();
|
||||||
|
|
||||||
|
if(!(rhsType instanceof FunNType))
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
/* muss nach angepasst werden */
|
||||||
|
//FunN$$<...> <. FunctinalInterface<...> wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
|
||||||
|
if (lhsType instanceof ReferenceType) {
|
||||||
|
UnifyType typeFI = pair.getLhsType();
|
||||||
|
|
||||||
|
Optional<UnifyType> opt = fc.getRightHandedFunctionalInterfaceType(typeFI.getName());
|
||||||
|
if(!opt.isPresent())
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
if (!(typeFI instanceof ReferenceType refType) || !(refType instanceof FunInterfaceType intf))
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
|
||||||
|
var retType = fiArgs.getFirst();
|
||||||
|
var rhsArgs = intf.getFunctionalInterfaceTypeArguments(rhsType);
|
||||||
|
var rhsRet = rhsArgs.getFirst();
|
||||||
|
|
||||||
|
Set<UnifyPair> result = new HashSet<>();
|
||||||
|
//if (retType instanceof ExtendsType) {
|
||||||
|
result.add(new UnifyPair(retType, rhsRet, PairOperator.EQUALSDOT));
|
||||||
|
//} else if (retType instanceof SuperType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
// result.add(new UnifyPair(lhsRet, retType, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
|
||||||
|
for (var i = 1; i < fiArgs.size(); i++) {
|
||||||
|
var rh = rhsArgs.get(i);
|
||||||
|
var lh = fiArgs.get(i);
|
||||||
|
|
||||||
|
//if (rh instanceof SuperType) {
|
||||||
|
result.add(new UnifyPair(rh, lh, PairOperator.EQUALSDOT));
|
||||||
|
//} else if (rh instanceof ExtendsType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
// result.add(new UnifyPair(lh, rh, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Set<UnifyPair>> reduceFunNFi(UnifyPair pair, IFiniteClosure fc) {
|
||||||
|
if(pair.getPairOp() != PairOperator.EQUALSDOT)
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
UnifyType lhsType = pair.getLhsType();
|
||||||
|
UnifyType rhsType = pair.getRhsType();
|
||||||
|
|
||||||
|
if(!(lhsType instanceof FunNType))
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
//FunN$$<...> <. FunctinalInterface<...> wird umgewandelt in FunN$$<...> <. FunN$$<... args aus FuntionalInterface ...>
|
||||||
|
if (rhsType instanceof ReferenceType) {
|
||||||
|
UnifyType typeFI = pair.getRhsType();
|
||||||
|
|
||||||
|
Optional<UnifyType> opt = fc.getRightHandedFunctionalInterfaceType(typeFI.getName());
|
||||||
|
if(!opt.isPresent())
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
if (!(typeFI instanceof ReferenceType refType) || !(refType instanceof FunInterfaceType intf))
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
var fiArgs = intf.getFunctionalInterfaceTypeArguments(refType);
|
||||||
|
var retType = fiArgs.getFirst();
|
||||||
|
var lhsArgs = intf.getFunctionalInterfaceTypeArguments(lhsType);
|
||||||
|
var lhsRet = lhsArgs.getFirst();
|
||||||
|
|
||||||
|
Set<UnifyPair> result = new HashSet<>();
|
||||||
|
//if (retType instanceof ExtendsType) {
|
||||||
|
// result.add(new UnifyPair(lhsRet, retType, PairOperator.SMALLERDOTWC));
|
||||||
|
//} else if (retType instanceof SuperType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
result.add(new UnifyPair(lhsRet, retType, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
|
||||||
|
for (var i = 1; i < fiArgs.size(); i++) {
|
||||||
|
var lh = lhsArgs.get(i);
|
||||||
|
var rh = fiArgs.get(i);
|
||||||
|
|
||||||
|
//if (rh instanceof SuperType) {
|
||||||
|
// result.add(new UnifyPair(lh, rh, PairOperator.SMALLERDOTWC));
|
||||||
|
//} else if (rh instanceof ExtendsType) {
|
||||||
|
// return Optional.empty();
|
||||||
|
//} else {
|
||||||
|
result.add(new UnifyPair(lh, rh, PairOperator.EQUALSDOT));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<UnifyPair> reduceTph(UnifyPair pair) {
|
public Optional<UnifyPair> reduceTph(UnifyPair pair) {
|
||||||
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
|
||||||
@@ -1025,7 +1190,7 @@ public class RuleSet implements IRuleSet{
|
|||||||
|
|
||||||
UnifyType lhsType = pair.getLhsType();
|
UnifyType lhsType = pair.getLhsType();
|
||||||
UnifyType rhsType = pair.getRhsType();
|
UnifyType rhsType = pair.getRhsType();
|
||||||
if(!(lhsType instanceof PlaceholderType) || !(rhsType instanceof ReferenceType))
|
if(!(lhsType instanceof PlaceholderType) || (!(rhsType instanceof ReferenceType) && !(rhsType instanceof FunNType)))
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
return Optional.of(new UnifyPair(lhsType, rhsType, PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import de.dhbwstuttgart.util.Logger;
|
|||||||
import de.dhbwstuttgart.util.Pair;
|
import de.dhbwstuttgart.util.Pair;
|
||||||
import de.dhbwstuttgart.util.Tuple;
|
import de.dhbwstuttgart.util.Tuple;
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -150,12 +151,15 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
|
|||||||
this.fc = fc;
|
this.fc = fc;
|
||||||
this.oup = new OrderingUnifyPair(fc, context);
|
this.oup = new OrderingUnifyPair(fc, context);
|
||||||
|
|
||||||
this.context = (!ConsoleInterface.writeLogFiles || context.logger() instanceof ServerTaskLogger) ? context : context.newWithLogger(
|
if (!ConsoleInterface.writeLogFiles || context.logger() instanceof ServerTaskLogger) this.context = context;
|
||||||
|
else {
|
||||||
|
var baseFolder = Path.of(System.getProperty("user.dir"), "logFiles");
|
||||||
|
this.context = context.newWithLogger(
|
||||||
Logger.forFile(
|
Logger.forFile(
|
||||||
System.getProperty("user.dir") + "/logFiles/" + "Thread",
|
baseFolder.resolve("Thread_" + Thread.currentThread().hashCode() + ".txt").toString(), "Unify"
|
||||||
"Unify"
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/*Abbruchtest
|
/*Abbruchtest
|
||||||
if (thNo > 10) {
|
if (thNo > 10) {
|
||||||
@@ -1239,7 +1243,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
|
|||||||
// FunN Rules
|
// FunN Rules
|
||||||
optSet = optSet.isPresent() ? optSet : rules.reduceFunN(pair);
|
optSet = optSet.isPresent() ? optSet : rules.reduceFunN(pair);
|
||||||
optSet = optSet.isPresent() ? optSet : rules.greaterFunN(pair, fc);
|
optSet = optSet.isPresent() ? optSet : rules.greaterFunN(pair, fc);
|
||||||
optSet = optSet.isPresent() ? optSet : rules.smallerFunN(pair);
|
optSet = optSet.isPresent() ? optSet : rules.smallerFunN(pair, fc);
|
||||||
|
|
||||||
// One of the rules has been applied
|
// One of the rules has been applied
|
||||||
if (optSet.isPresent()) {
|
if (optSet.isPresent()) {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ public class UnifyResultModel {
|
|||||||
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet, UnifyContext context) {
|
public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet, UnifyContext context) {
|
||||||
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
|
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
|
||||||
Optional<Set<UnifyPair>> res = new RuleSet(context.placeholderRegistry()).subst(x.stream().map(y -> {
|
Optional<Set<UnifyPair>> res = new RuleSet(context.placeholderRegistry()).subst(x.stream().map(y -> {
|
||||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
|
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
||||||
|
y.setPairOp(PairOperator.EQUALSDOT);
|
||||||
return y; //alle Paare a <.? b erden durch a =. b ersetzt
|
return y; //alle Paare a <.? b erden durch a =. b ersetzt
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
}).collect(Collectors.toCollection(HashSet::new)));
|
||||||
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
|
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ public interface IRuleSet {
|
|||||||
*/
|
*/
|
||||||
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
|
public Optional<Set<UnifyPair>> reduceFunN(UnifyPair pair);
|
||||||
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair, IFiniteClosure fc);
|
public Optional<Set<UnifyPair>> greaterFunN(UnifyPair pair, IFiniteClosure fc);
|
||||||
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair);
|
public Optional<Set<UnifyPair>> smallerFunN(UnifyPair pair, IFiniteClosure fc);
|
||||||
|
public Optional<Set<UnifyPair>> reduceFIFunN(UnifyPair pair, IFiniteClosure fc);
|
||||||
|
public Optional<Set<UnifyPair>> reduceFunNFi(UnifyPair pair, IFiniteClosure fc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the erase1-Rule applies to the pair.
|
* Checks whether the erase1-Rule applies to the pair.
|
||||||
|
|||||||
@@ -685,6 +685,7 @@ public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-1
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UnifyType> getAncestors(UnifyType t) {
|
public Set<UnifyType> getAncestors(UnifyType t) {
|
||||||
if (!inheritanceGraph.containsKey(t))
|
if (!inheritanceGraph.containsKey(t))
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package de.dhbwstuttgart.util;
|
|||||||
import com.diogonunes.jcolor.Attribute;
|
import com.diogonunes.jcolor.Attribute;
|
||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
import de.dhbwstuttgart.server.SocketServer;
|
import de.dhbwstuttgart.server.SocketServer;
|
||||||
import java.io.File;
|
import org.apache.commons.io.FileUtils;
|
||||||
import java.io.FileWriter;
|
import org.apache.commons.io.output.NullOutputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -19,12 +21,44 @@ import static com.diogonunes.jcolor.Ansi.colorize;
|
|||||||
|
|
||||||
public class Logger {
|
public class Logger {
|
||||||
|
|
||||||
public static final Logger NULL_LOGGER = new NullLogger();
|
|
||||||
private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
protected final Writer writer;
|
protected final Writer writer;
|
||||||
protected final String prefix;
|
protected final String prefix;
|
||||||
|
|
||||||
|
private static final File logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
|
||||||
|
public static final Logger NULL_LOGGER = new NullLogger();
|
||||||
|
|
||||||
|
private static Writer defaultWriter;
|
||||||
|
private static void initLogger() {
|
||||||
|
if (defaultWriter != null) return;
|
||||||
|
if (ConsoleInterface.writeLogFiles) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(logFolder.toPath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Could not create directory for log files: " + logFolder, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
|
||||||
|
var currentTimestamp = LocalDateTime.now().format(formatter);
|
||||||
|
try {
|
||||||
|
defaultWriter = new FileWriter(new File(logFolder, currentTimestamp + ".txt"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetLogs() {
|
||||||
|
defaultWriter = null;
|
||||||
|
try {
|
||||||
|
FileUtils.cleanDirectory(logFolder);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
initLogger();
|
||||||
|
}
|
||||||
|
|
||||||
public Logger() {
|
public Logger() {
|
||||||
this(null, "");
|
this(null, "");
|
||||||
}
|
}
|
||||||
@@ -35,9 +69,15 @@ public class Logger {
|
|||||||
|
|
||||||
public Logger(Writer writer, String prefix) {
|
public Logger(Writer writer, String prefix) {
|
||||||
this.prefix = (Objects.equals(prefix, "")) ? "" : "["+prefix+"] ";
|
this.prefix = (Objects.equals(prefix, "")) ? "" : "["+prefix+"] ";
|
||||||
|
initLogger();
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Writer getWriter() {
|
||||||
|
if (writer != null) return writer;
|
||||||
|
return defaultWriter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new logger object from the path provided
|
* Create a new logger object from the path provided
|
||||||
*
|
*
|
||||||
@@ -87,6 +127,7 @@ public class Logger {
|
|||||||
* @param logLevel If logLevel == error, then print to stderr or print to stdout otherwise
|
* @param logLevel If logLevel == error, then print to stderr or print to stdout otherwise
|
||||||
*/
|
*/
|
||||||
protected void print(String s, LogLevel logLevel) {
|
protected void print(String s, LogLevel logLevel) {
|
||||||
|
if (!ConsoleInterface.writeToConsole) return;
|
||||||
String coloredPrefix = this.getPrefix(logLevel);
|
String coloredPrefix = this.getPrefix(logLevel);
|
||||||
|
|
||||||
// if we are running the server, prepend the timestamp
|
// if we are running the server, prepend the timestamp
|
||||||
@@ -113,11 +154,13 @@ public class Logger {
|
|||||||
* @param s The string to print
|
* @param s The string to print
|
||||||
*/
|
*/
|
||||||
protected void write(String s) {
|
protected void write(String s) {
|
||||||
|
var writer = getWriter();
|
||||||
if (writer != null && ConsoleInterface.writeLogFiles) {
|
if (writer != null && ConsoleInterface.writeLogFiles) {
|
||||||
// writing to file should only be done when necessary
|
// writing to file should only be done when necessary
|
||||||
synchronized (writer) {
|
synchronized (writer) {
|
||||||
try {
|
try {
|
||||||
writer.write(s);
|
writer.write(s + "\n");
|
||||||
|
writer.flush();
|
||||||
}
|
}
|
||||||
catch (IOException exception) {
|
catch (IOException exception) {
|
||||||
throw new RuntimeException("Failed writing to file", exception);
|
throw new RuntimeException("Failed writing to file", exception);
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.util.Logger.LogLevel;
|
||||||
|
|
||||||
public class AllgemeinTest {
|
public class AllgemeinTest {
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ public class AllgemeinTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
|
ConsoleInterface.logLevel = LogLevel.DEBUG;
|
||||||
//String className = "GenTest";
|
//String className = "GenTest";
|
||||||
//String className = "Overloading_Generics";
|
//String className = "Overloading_Generics";
|
||||||
//String className = "Generics";
|
//String className = "Generics";
|
||||||
@@ -55,6 +58,7 @@ public class AllgemeinTest {
|
|||||||
//String className = "WildcardCaptureConversionTest";
|
//String className = "WildcardCaptureConversionTest";
|
||||||
//String className = "CaptureConversion";
|
//String className = "CaptureConversion";
|
||||||
//String className = "Pair";
|
//String className = "Pair";
|
||||||
|
//String className = "DublicateWildcard";
|
||||||
//String className = "UseWildcardPair";
|
//String className = "UseWildcardPair";
|
||||||
//String className = "Assign";
|
//String className = "Assign";
|
||||||
//String className = "StreamTest";
|
//String className = "StreamTest";
|
||||||
@@ -63,11 +67,14 @@ public class AllgemeinTest {
|
|||||||
//String className = "Cycle";
|
//String className = "Cycle";
|
||||||
//String className = "TripleTest";
|
//String className = "TripleTest";
|
||||||
//String className = "WildcardList";
|
//String className = "WildcardList";
|
||||||
String className = "List";
|
//String className = "List";
|
||||||
//String className = "Box";
|
//String className = "Box";
|
||||||
//String className = "GenBox";
|
//String className = "GenBox";
|
||||||
//String className = "InnerInf";
|
//String className = "InnerInf";
|
||||||
//String className = "Foo";
|
//String className = "Foo";
|
||||||
|
//String className = "Kombinatoren_failure";
|
||||||
|
String className = "Kombinatoren_After_Lazy";
|
||||||
|
//String className = "Parser";
|
||||||
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
//PL 2019-10-24: genutzt fuer unterschiedliche Tests
|
||||||
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
path = System.getProperty("user.dir")+"/resources/AllgemeinTest/" + className + ".jav";
|
||||||
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
//path = System.getProperty("user.dir")+"/src/test/resources/AllgemeinTest/Overloading_Generics.jav";
|
||||||
@@ -76,7 +83,7 @@ public class AllgemeinTest {
|
|||||||
///*
|
///*
|
||||||
compiler = new JavaTXCompiler(
|
compiler = new JavaTXCompiler(
|
||||||
Lists.newArrayList(new File(path)),
|
Lists.newArrayList(new File(path)),
|
||||||
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/")),
|
Lists.newArrayList(new File(System.getProperty("user.dir")+"/resources/AllgemeinTest/")),
|
||||||
new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"), true);
|
new File(System.getProperty("user.dir")+"/resources/bytecode/classFiles/"), true);
|
||||||
//*/
|
//*/
|
||||||
compiler.generateBytecode();
|
compiler.generateBytecode();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
import de.dhbwstuttgart.util.Logger;
|
import de.dhbwstuttgart.util.Logger;
|
||||||
|
import de.dhbwstuttgart.util.Logger.LogLevel;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -764,6 +766,8 @@ public class TestComplete {
|
|||||||
assertEquals("Second Element is a Text", swtch.invoke(instance, r1));
|
assertEquals("Second Element is a Text", swtch.invoke(instance, r1));
|
||||||
assertEquals("Second Element is a Number", swtch.invoke(instance, r2));
|
assertEquals("Second Element is a Number", swtch.invoke(instance, r2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Disabled("Infinite loop in type inference")
|
||||||
@Test
|
@Test
|
||||||
public void testSwitchListRecord() throws Exception {
|
public void testSwitchListRecord() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "SwitchRecordList.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "SwitchRecordList.jav");
|
||||||
@@ -972,9 +976,37 @@ public class TestComplete {
|
|||||||
assertEquals(1, m.invoke(instance, r));
|
assertEquals(1, m.invoke(instance, r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPatternMatchingCaptures() throws Exception {
|
||||||
|
var classFiles = generateClassFiles(createClassLoader(), "PatternMatchingCaptures.jav");
|
||||||
|
|
||||||
|
var clazz = classFiles.get("PatternMatchingCaptures");
|
||||||
|
var R = classFiles.get("R");
|
||||||
|
var Base = classFiles.get("Base");
|
||||||
|
var r = R.getDeclaredConstructor(Integer.class).newInstance(10);
|
||||||
|
|
||||||
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
var test1 = clazz.getDeclaredMethod("test1", Base);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
|
||||||
|
var test2 = clazz.getDeclaredMethod("test2", Base);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
|
||||||
|
var test3 = clazz.getDeclaredMethod("test3", R);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
|
||||||
|
var test4 = clazz.getDeclaredMethod("test4", R);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
|
||||||
|
var test5 = clazz.getDeclaredMethod("test5", R);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
|
||||||
|
var test6 = clazz.getDeclaredMethod("test6", R);
|
||||||
|
assertEquals(10, test1.invoke(instance, r));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingZip() throws Exception {
|
public void testPatternMatchingZip() throws Exception {
|
||||||
//ConsoleInterface.logLevel = Logger.LogLevel.DEBUG;
|
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "PatternMatching.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "PatternMatching.jav");
|
||||||
var clazz = classFiles.get("PatternMatching");
|
var clazz = classFiles.get("PatternMatching");
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
@@ -993,6 +1025,7 @@ public class TestComplete {
|
|||||||
System.out.println(zip.invoke(instance, list1, list2));
|
System.out.println(zip.invoke(instance, list1, list2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Disabled("Invalid file, check this later")
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingZipJava() throws Exception {
|
public void testPatternMatchingZipJava() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), false, "PatternMatchingJava.jav", "PatternMatchingJava2.jav");
|
var classFiles = generateClassFiles(createClassLoader(), false, "PatternMatchingJava.jav", "PatternMatchingJava2.jav");
|
||||||
@@ -1416,6 +1449,7 @@ public class TestComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Disabled("too slow")
|
||||||
public void testBug325() throws Exception {
|
public void testBug325() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "Bug325.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "Bug325.jav");
|
||||||
var clazz = classFiles.get("Bug325");
|
var clazz = classFiles.get("Bug325");
|
||||||
|
|||||||
Reference in New Issue
Block a user