11 Commits

Author SHA1 Message Date
Fabian Holzwarth
c5c31bc372 Merge branch 'feat/unify-server' into feat/unify-server-0variance 2025-07-07 11:12:39 +02:00
Fabian Holzwarth
03042fab97 feat: apply result for all parallel results on variance 0 2025-07-05 14:17:59 +02:00
Fabian Holzwarth
8d5b4ff54f Merge branch 'feat/unify-server' into feat/unify-server-0variance 2025-07-02 17:14:05 +02:00
Fabian Holzwarth
e8335715fb Merge branch 'feat/unify-server-0variance' of ssh://gitea.hb.dhbw-stuttgart.de:2222/f.holzwarth/JavaCompilerCore into feat/unify-server-0variance 2025-07-01 23:11:43 +02:00
Fabian Holzwarth
e574174962 feat: undo some changes for testing 2025-07-01 23:09:33 +02:00
Fabian Holzwarth
6df99fcacb feat: prevent concurrent list access on cancellable task 2025-07-01 23:08:41 +02:00
Fabian Holzwarth
d3fbaea8c7 feat: introduce task cancelling 2025-07-01 23:08:41 +02:00
Fabian Holzwarth
3415c250a3 feat: select multiple elements for variance 0 2025-07-01 23:08:39 +02:00
Fabian Holzwarth
9ec32970ee feat: prevent concurrent list access on cancellable task 2025-06-30 22:53:25 +02:00
Fabian Holzwarth
c54e012426 feat: introduce task cancelling 2025-06-30 22:20:52 +02:00
Fabian Holzwarth
52f6ebcf3c feat: select multiple elements for variance 0 2025-06-30 16:43:39 +02:00
45 changed files with 606 additions and 1238 deletions

View File

@@ -9,8 +9,7 @@ mkdir $TDIR
cd $TDIR cd $TDIR
git clone $REPO . git clone $REPO .
git checkout feat/unify-server git checkout feat/unify-server-0variance
# git checkout 93e1a8787cd94c73f4538f6a348f58613893a584
# git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55 # git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55
# git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25 # git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25
# git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27 # git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27
@@ -20,14 +19,14 @@ git checkout feat/unify-server
# git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29 # git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29
date "+%Y.%m.%d %H:%M:%S" date "+%Y.%m.%d %H:%M:%S"
# sed -i -e 's/source>21/source>23/g' pom.xml
# sed -i -e 's/target>21/target>23/g' pom.xml mkdir testOut
#mvn clean compile -DskipTests package
#time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Merge.jav -vv -d testOut;
mvn clean compile -DskipTests package mvn clean compile test
time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav;
# mvn clean compile test
echo -e "\nCleanup... " echo -e "\nCleanup... "

View File

@@ -49,11 +49,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>Java-WebSocket</artifactId> <artifactId>Java-WebSocket</artifactId>
<version>1.5.2</version> <version>1.5.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>

View File

@@ -1,51 +0,0 @@
class C1 {
C1 self() {
return this;
}
}
class C2 {
C2 self() {
return this;
}
}
class Example {
untypedMethod(var) {
return var.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self()
.self().self().self().self();
}
}

View File

@@ -1,43 +0,0 @@
import java.lang.Integer;
import java.lang.Boolean;
import java.util.Queue;
import java.util.Vector;
import java.util.List;
import java.util.ArrayDeque;
class Pos {
public Integer x;
public Integer y;
public Pos(Integer x, Integer y) {
this.x = x;
this.y = y;
}
}
class GridSearch {
Pos search(Vector<Vector<Boolean>> grid) {
var w = grid.size();
var h = grid.getFirst().size();
// keep a queue on which cells to check
var cellQueue = new ArrayDeque<Pos>();
cellQueue.add(new Pos(0,0));
while (!cellQueue.isEmpty()) {
var pos = cellQueue.poll();
// if the target was found: return the position
var value = grid.get(pos.x).get(pos.y);
if (value) {
return pos;
}
// keep searching on neighboring tiles
if (pos.x < w-1) cellQueue.add(new Pos(pos.x + 1, pos.y));
if (pos.y < h-1) cellQueue.add(new Pos(pos.x, pos.y + 1));
}
return (Pos)null;
}
}

View File

@@ -1,42 +0,0 @@
import java.util.List;
import java.util.AbstractList;
import java.util.Vector;
import java.lang.Integer;
class Pixel {
public color;
}
class Mask {
mask;
Mask(mask) {
this.mask = mask;
}
apply(pixels) {
var w = mask.size();
var h = mask.get(0).size();
var imgW = pixels.size();
var imgH = pixels.get(0).size();
for (var x = 0; x < imgW - w; x++) {
for (var y = 0; y < imgH - h; y++) {
var total = 0;
for (var xd = 0; xd < w; xd++) {
for (var yd = 0; yd < h; yd++) {
var p = pixels.get(x + xd).get(y + yd);
var m = mask.get(xd).get(yd);
total = total + (p.color * m);
}
}
pixels.get(x).get(y).color = total;
}
}
return pixels;
}
}

View File

@@ -1,39 +0,0 @@
import java.lang.Integer;
import java.lang.Boolean;
import java.util.ArrayList;
import java.util.HashMap;
public class PascalsTriangle {
create(n) {
var rows = new ArrayList<ArrayList<Integer>>();
var evens = new ArrayList<ArrayList<Boolean>>();
if (n <= 0) return rows;
// first row
rows.add(new ArrayList<Integer>(1));
evens.add(new ArrayList<Boolean>(false));
for (int y = 1; y < n; y++) {
var row = new ArrayList<Integer>();
var evensRow = new ArrayList<Boolean>();
row.add(1);
evensRow.add(false);
for (int x = 1; x < y-1; x++) {
int tl = rows.getLast().get(x-1);
int tr = rows.getLast().get(x);
row.add(tl + tr);
evensRow.add(((tl + tr) % 2) == 1);
}
row.add(1);
rows.add(row);
evensRow.add(false);
evens.add(evensRow);
}
return rows;
}
}

View File

@@ -1,17 +0,0 @@
import java.util.List;
import java.lang.Integer;
//import java.util.Collection;
public class Merge2 {
public merge(a, b) {
a.addAll(b);
return a;
}
public sort(in){
var firstHalf = in.subList(1,2);
return merge(sort(firstHalf), sort(in));
}
}

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -8,12 +7,8 @@ import java.util.*;
public class ConsoleInterface { public class ConsoleInterface {
/**
* Leave the argument configurations here for the rest of the code to read
*/
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR; public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
public static boolean writeLogFiles = false; public static boolean writeLogFiles = false;
public static Optional<String> unifyServerUrl = Optional.empty();
public static void main(String[] args) throws IOException, ClassNotFoundException { public static void main(String[] args) throws IOException, ClassNotFoundException {
List<File> input = new ArrayList<>(); List<File> input = new ArrayList<>();
@@ -21,6 +16,7 @@ public class ConsoleInterface {
String outputPath = null; String outputPath = null;
Iterator<String> it = Arrays.asList(args).iterator(); Iterator<String> it = Arrays.asList(args).iterator();
Optional<Integer> serverPort = Optional.empty(); Optional<Integer> serverPort = Optional.empty();
Optional<String> unifyServer = Optional.empty();
if (args.length == 0) { if (args.length == 0) {
System.out.println("No input files given. Get help with --help"); System.out.println("No input files given. Get help with --help");
@@ -49,7 +45,7 @@ public class ConsoleInterface {
} else if (arg.equals("--server-mode")) { } else if (arg.equals("--server-mode")) {
serverPort = Optional.of(Integer.parseInt(it.next())); serverPort = Optional.of(Integer.parseInt(it.next()));
} else if (arg.equals("--unify-server")) { } else if (arg.equals("--unify-server")) {
unifyServerUrl = Optional.of(it.next()); unifyServer = Optional.of(it.next());
} else if (arg.equals("--write-logs")) { } else if (arg.equals("--write-logs")) {
ConsoleInterface.writeLogFiles = true; ConsoleInterface.writeLogFiles = true;
} else if (arg.startsWith("-v")) { } else if (arg.startsWith("-v")) {
@@ -65,15 +61,15 @@ public class ConsoleInterface {
} }
if (serverPort.isPresent()) { if (serverPort.isPresent()) {
if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!"); if (unifyServer.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
JavaTXServer server = new JavaTXServer(serverPort.get()); JavaTXServer server = new JavaTXServer(serverPort.get());
server.listen(); server.listen();
} }
else { else {
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null); JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null, unifyServer);
//compiler.typeInference(); //compiler.typeInference();
compiler.generateBytecode(); compiler.generateBytecode();
SocketClient.closeIfOpen();
} }
} }

View File

@@ -13,10 +13,6 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.packet.SetAutoclosePacket;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
@@ -24,7 +20,6 @@ import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
@@ -86,24 +81,29 @@ public class JavaTXCompiler {
public final List<File> classPath; public final List<File> classPath;
private final File outputPath; private final File outputPath;
private final Optional<String> unifyServer;
public DirectoryClassLoader getClassLoader() { public DirectoryClassLoader getClassLoader() {
return classLoader; return classLoader;
} }
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Collections.singletonList(sourceFile), List.of(), new File(".")); this(Arrays.asList(sourceFile), List.of(), new File("."), Optional.empty());
} }
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, List.of(), new File(".")); this(sourceFiles, List.of(), new File("."), Optional.empty());
} }
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException {
this(sources, contextPath, outputPath, Optional.empty());
}
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath, Optional<String> unifyServer) throws IOException, ClassNotFoundException {
// ensure new default placeholder registry for tests // ensure new default placeholder registry for tests
defaultClientPlaceholderRegistry = new PlaceholderRegistry(); defaultClientPlaceholderRegistry = new PlaceholderRegistry();
NameGenerator.reset();
ASTToTargetAST.OBJECT = ASTFactory.createObjectType();
this.unifyServer = unifyServer;
var path = new ArrayList<>(contextPath); var path = new ArrayList<>(contextPath);
if (contextPath.isEmpty()) { if (contextPath.isEmpty()) {
// When no contextPaths are given, the working directory is the sources root // When no contextPaths are given, the working directory is the sources root
@@ -425,14 +425,11 @@ public class JavaTXCompiler {
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new)) * Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
*/; */;
if (ConsoleInterface.unifyServerUrl.isPresent()) { if (unifyServer.isPresent()) {
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure); UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry); UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
SocketFuture<UnifyResultPacket> future = SocketClient.execute( SocketClient socketClient = new SocketClient(unifyServer.get());
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry()) return socketClient.execute(finiteClosure, cons, unifyCons, context);
);
SocketClient.execute(SetAutoclosePacket.create());
return future.get().getResultSet(context);
} }
else if (resultmodel) { else if (resultmodel) {
/* UnifyResultModel Anfang */ /* UnifyResultModel Anfang */
@@ -672,7 +669,7 @@ public class JavaTXCompiler {
output = new FileOutputStream(outputFile); output = new FileOutputStream(outputFile);
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
defaultLogger.success(name + ".class file generated"); defaultLogger.info(name + ".class file generated");
} }
} }

View File

@@ -10,10 +10,10 @@ public class JavaTXServer {
public JavaTXServer(int port) { public JavaTXServer(int port) {
this.socketServer = new SocketServer(port); this.socketServer = new SocketServer(port);
isRunning = true;
} }
public void listen() { public void listen() {
isRunning = true;
socketServer.start(); socketServer.start();
} }

View File

@@ -1,41 +0,0 @@
package de.dhbwstuttgart.server;
import de.dhbwstuttgart.util.Logger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.java_websocket.WebSocket;
public class ServerTaskLogger extends Logger {
private final WebSocket webSocket;
private final SocketServer socketServer;
private final LogLevel customLogLevel;
public ServerTaskLogger(WebSocket webSocket, SocketServer socketServer, LogLevel customLogLevel) {
this.webSocket = webSocket;
this.socketServer = socketServer;
this.customLogLevel = customLogLevel;
}
@Override
public boolean isLogLevelActive(LogLevel logLevel) {
return logLevel.isHigherOrEqualTo(customLogLevel);
}
@Override
protected void print(String s, LogLevel logLevel) {
String coloredPrefix = this.getPrefix(logLevel);
if (logLevel.isHigherOrEqualTo(LogLevel.ERROR)) {
socketServer.sendError(webSocket, coloredPrefix + s, false);
}
else {
socketServer.sendMessage(webSocket, coloredPrefix + s);
}
}
@Override
protected void write(String s) {
// under no circumstances write anything to a file
}
}

View File

@@ -1,8 +1,6 @@
package de.dhbwstuttgart.server; package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.IServerToClientPacket; import de.dhbwstuttgart.server.packet.IServerToClientPacket;
import de.dhbwstuttgart.server.packet.PacketContainer; import de.dhbwstuttgart.server.packet.PacketContainer;
@@ -16,10 +14,8 @@ import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.net.URI; import java.net.URI;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -35,31 +31,43 @@ public class SocketClient extends WebSocketClient {
public static Logger logger = new Logger("SocketClient"); public static Logger logger = new Logger("SocketClient");
/** // use a latch to wait until the connection is closed by the remote host
* The singleton object private final CountDownLatch closeLatch = new CountDownLatch(1);
*/ // temporarily: The received unify result
private static SocketClient socketClient = null; // TODO: replace with uuid and future system, such that responses can be mapped by a uuid to fulfill a Future
private UnifyResultPacket unifyResultPacket;
/** public SocketClient(String url) {
* List of futures that are still waiting to be fulfilled
*/
private final Map<String, SocketFuture<?>> responseFutures = new HashMap<>();
private SocketClient(String url) {
super( super(
URI.create(url), // target url URI.create(url), // target url
//SocketServer.perMessageDeflateDraft, // enable compression SocketServer.perMessageDeflateDraft, // enable compression
Map.of( // headers Map.of( // headers
"packetProtocolVersion", SocketServer.packetProtocolVersion "packetProtocolVersion", SocketServer.packetProtocolVersion
) )
); );
// make sure, the url is in a valid format
// make sure the url is in a valid format
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$"; final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
final Matcher matcher = Pattern.compile(regex).matcher(url); final Matcher matcher = Pattern.compile(regex).matcher(url);
if (!matcher.find()) { if (!matcher.find()) {
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>"); throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
} }
}
public SocketClient(String host, int port, boolean secure) {
this(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port));
}
/**
* The main method for connecting, requesting and waiting for the server to unify.
* This is synchronized to prevent multiple webSockets connections at the moment, but it is not called from any
* thread except the main thread right now and is not necessary at all, probably. Maybe remove it later
*/
synchronized public List<ResultSet> execute(
FiniteClosure finiteClosure,
ConstraintSet<Pair> constraintSet,
ConstraintSet<UnifyPair> unifyConstraintSet,
UnifyContext context
) throws JsonProcessingException {
try { try {
// wait for the connection to be set up // wait for the connection to be set up
@@ -68,108 +76,60 @@ public class SocketClient extends WebSocketClient {
if (this.getReadyState() != ReadyState.OPEN) { if (this.getReadyState() != ReadyState.OPEN) {
throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri); throw new RuntimeException("WebSocket Client could not connect to remote host at " + this.uri);
} }
} catch (InterruptedException exception) {
throw new RuntimeException(exception);
}
// add a shutdown hook to close the connection when the process ends or is stopped by a SIGINT signal // send the unify task request
Runtime.getRuntime().addShutdownHook(new Thread(this::close)); UnifyRequestPacket packet = new UnifyRequestPacket(finiteClosure, constraintSet, unifyConstraintSet, context.placeholderRegistry());
}
private SocketClient(String host, int port, boolean secure) throws InterruptedException {
this(String.format("%s://%s:%d/", secure ? "wss" : "ws", host, port));
}
/**
* Singleton access method, creates one if none is available
*
* @return The one and only socketClient
*/
private static SocketClient initializeClient() {
if (socketClient == null) {
socketClient = new SocketClient(ConsoleInterface.unifyServerUrl.get());
}
return socketClient;
}
/**
* Send a packet to the server (connection will be created, if none is found) and return a future
* for the response packet
*/
synchronized public static <T extends IServerToClientPacket> SocketFuture<T> execute(IClientToServerPacket<T> packet) {
SocketClient client = initializeClient();
/*
* Create a future that will be associated with the packet and eventually completed
*/
SocketFuture<T> future = packet.getFuture();
if (!future.isDone()) {
client.responseFutures.put(future.futureId, future);
}
/*
* Establish connection, if not already done.
* Serialize the packet and send it to the server.
* Return the future to be handled by the caller.
*/
try {
String json = PacketContainer.serialize(packet); String json = PacketContainer.serialize(packet);
client.send(json); this.send(json);
// block the thread, until the connection is closed by the remote host (usually after sending the results)
this.waitUntilClosed();
// wait for the connection to fully close
this.closeBlocking();
} catch (InterruptedException exception) {
System.err.println("Server connection interrupted: " + exception);
this.notifyAll();
throw new RuntimeException("Aborted server connection", exception);
} catch (Exception exception) { } catch (Exception exception) {
logger.exception(exception);
throw new RuntimeException("Exception occurred in server connection: ", exception); throw new RuntimeException("Exception occurred in server connection: ", exception);
} }
return future; // detect error cases, in which no error was thrown, but also no result was sent back from the server
if (this.unifyResultPacket == null) {
throw new RuntimeException("Did not receive server response but closed connection already");
} }
/** return unifyResultPacket.getResultSet(context);
* Shortcut for waiting and retrieving the response immediately
*
* @param packet The packet to send
* @param <T> The type of response packet to await
* @return The response packet, once it is received
*/
public static <T extends IServerToClientPacket> T executeAndGet(IClientToServerPacket<T> packet) {
return SocketClient.execute(packet).get();
} }
/** /**
* Specific client-side implementations to handle incoming packets * Specific client-side implementations to handle incoming packets
*/ */
protected void handleReceivedPacket(IPacket packet) { protected void handleReceivedPacket(IPacket packet) {
if (!(packet instanceof IServerToClientPacket serverToClientPacket)) { if (packet instanceof IServerToClientPacket serverToClientPacket) {
System.err.println("Received package of invalid type + " + packet.getClass().getName());
try {
serverToClientPacket.onHandle(this.getConnection(), this);
} catch (Exception exception) {
this.closeLatch.countDown();
this.close(); this.close();
throw exception;
}
return; return;
} }
serverToClientPacket.onHandle(this.getConnection(), this); System.err.println("Received package of invalid type + " + packet.getClass().getName());
this.close();
} }
/** public void setUnifyResultSets(UnifyResultPacket unifyResultPacket) {
* Complete a registered future, so it can be handled by whoever executed the creator task this.unifyResultPacket = unifyResultPacket;
*
* @param id The associated id for this future
* @param trigger The object triggering the completion
*/
public void completeResponseFuture(String id, IServerToClientPacket trigger) {
SocketFuture<?> future = this.responseFutures.remove(id);
if (future == null) return;
if (!future.accept(trigger)) {
throw new RuntimeException("Packet " + trigger.getClass().getName() + " tried to complete future, but was not allowed to");
}
}
public static void closeIfOpen() {
if (socketClient != null && socketClient.isOpen()) {
socketClient.close();
}
} }
@Override @Override
public void onOpen(ServerHandshake handshakedata) { public void onOpen(ServerHandshake handshakedata) {
logger.success("Connected to server with status " + handshakedata.getHttpStatus()); logger.info("Connected to server with status " + handshakedata.getHttpStatus());
} }
@Override @Override
@@ -187,16 +147,16 @@ public class SocketClient extends WebSocketClient {
(reason.isEmpty() ? "" : "and reason " + reason + " ") + (reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by remote: " + remote + ")" "(closed by remote: " + remote + ")"
); );
this.closeLatch.countDown();
if (!this.responseFutures.isEmpty()) {
throw new RuntimeException("Server closed before all required tasks were answered");
}
} }
@Override @Override
public void onError(Exception e) { public void onError(Exception e) {
logger.exception(e); logger.error("Error: " + e.getMessage());
throw new RuntimeException(e); e.printStackTrace();
} }
public void waitUntilClosed() throws InterruptedException {
closeLatch.await();
}
} }

View File

@@ -1,48 +0,0 @@
package de.dhbwstuttgart.server;
import de.dhbwstuttgart.server.packet.IServerToClientPacket;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class SocketFuture<T extends IServerToClientPacket> extends CompletableFuture<T> {
public final String futureId = UUID.randomUUID().toString();
public final List<Class<T>> allowedTriggers;
public SocketFuture(List<Class<T>> allowedTriggers) {
this.allowedTriggers = allowedTriggers;
}
public boolean accept(IServerToClientPacket trigger) {
if (this.allowedTriggers.contains(trigger.getClass())) {
this.complete((T)trigger);
return true;
}
return false;
}
@Override
public T get() {
try {
return super.get();
}
catch (InterruptedException | ExecutionException exception) {
throw new RuntimeException(exception);
}
}
/**
* Special case where the future is immediately fulfilled without a response package similar to
* <code>CompletableFuture.completedFuture()</code> but without a value
*/
public static <R extends IServerToClientPacket> SocketFuture<R> completedFuture() {
SocketFuture<R> dummyFuture = new SocketFuture<>(new ArrayList<>(0));
dummyFuture.complete(null);
return dummyFuture;
}
}

View File

@@ -1,6 +1,7 @@
package de.dhbwstuttgart.server; package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.server.packet.ErrorPacket; import de.dhbwstuttgart.server.packet.ErrorPacket;
import de.dhbwstuttgart.server.packet.IClientToServerPacket; import de.dhbwstuttgart.server.packet.IClientToServerPacket;
import de.dhbwstuttgart.server.packet.IPacket; import de.dhbwstuttgart.server.packet.IPacket;
@@ -9,13 +10,11 @@ import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Collections; import java.util.Collections;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
@@ -23,83 +22,67 @@ import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455; import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension; import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.DefaultWebSocketServerFactory;
import org.java_websocket.server.WebSocketServer; import org.java_websocket.server.WebSocketServer;
public class SocketServer extends WebSocketServer { public class SocketServer extends WebSocketServer {
public static Logger logger = new Logger("SocketServer"); public static Logger logger = new Logger("SocketServer");
public static final int maxTasksPerSession = 100;
private static boolean serverRunning = false;
/** /**
* Increase this every time a breaking change to the server communication is done. * Increase this every time a breaking change to the server communication is done.
* This will prevent errors when the server version and client version do not match. * This will prevent errors when server version and client version do not match.
*/ */
public static final String packetProtocolVersion = "1"; public static final String packetProtocolVersion = "1";
// create an executor for tasks that will always keep at least one task around /**
private final ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(1, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<>()); * Draft object for enabling the perMessageDeflate extension for more packet compression
// create an executor for scheduling timeouts */
private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); public static final Draft perMessageDeflateDraft = new Draft_6455(new PerMessageDeflateExtension());
public SocketServer(int port) { public SocketServer(int port) {
super(new InetSocketAddress(port)); super(new InetSocketAddress(port), Collections.singletonList(perMessageDeflateDraft));
this.setConnectionLostTimeout(30); this.setConnectionLostTimeout(30);
serverRunning = true;
// add a shutdown hook to close all connections when the process ends or is stopped by a SIGINT signal
Runtime.getRuntime().addShutdownHook(new Thread(this::onShutdown));
}
public static boolean isServerRunning() {
return serverRunning;
}
private void onShutdown() {
serverRunning = false;
try {
for (var webSocket : this.getConnections()) {
this.sendError(webSocket, "Sorry, i am shutting down. You are now on your own, good Luck!", true);
webSocket.close();
}
this.stop();
taskExecutor.shutdown();
timeoutExecutor.shutdown();
} catch (InterruptedException exception) {
// we are shutting down anyway
}
} }
@Override @Override
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) { public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
String ppv = clientHandshake.getFieldValue("packetProtocolVersion"); String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
if (!ppv.equals(packetProtocolVersion)) { if (!ppv.equals(packetProtocolVersion)) {
this.sendError(webSocket, try {
"Mismatch in packet protocol version! Client (you): \"" + ppv + "\" and Server (me): \"" + packetProtocolVersion + "\"", ErrorPacket errorPacket = ErrorPacket.create(
"Mismatch in packet protocol version! Client (you): " + ppv + " and Server (me): " + packetProtocolVersion,
true true
); );
webSocket.send(PacketContainer.serialize(errorPacket));
}
catch (JsonProcessingException exception) {
System.err.println("Failed to serialize json: " + exception);
}
webSocket.close(1); webSocket.close(1);
return; return;
} }
SocketData socketData = new SocketData(webSocket);
SocketData socketData = new SocketData(UUID.randomUUID().toString());
webSocket.setAttachment(socketData);
logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")"); logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")");
try { try {
sendMessage(webSocket, "Welcome to the server!"); sendMessage(webSocket, "Welcome to the server!");
// wait 10 seconds for the client to send a task and close the connection if nothing has been received until then // wait 10 seconds for the client to send a task and close the connection if nothing has been received until then
final int secondsUntilTimeout = 10; try (ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor()) {
timeoutExecutor.schedule(() -> { Runnable task = () -> {
if (webSocket.<SocketData>getAttachment().totalTasks.get() > 0 || !webSocket.isOpen()) { if (webSocket.<SocketData>getAttachment().unhandledTasks.get() == 0 || !webSocket.isOpen()) {
return; return;
} }
sendMessage(webSocket, "No task received after " + secondsUntilTimeout + " seconds. Closing connection..."); sendMessage(webSocket, "No task received after 10 seconds. Closing connection...");
webSocket.close(); webSocket.close();
}, };
secondsUntilTimeout, executor.schedule(task, 10, TimeUnit.SECONDS);
TimeUnit.SECONDS executor.shutdown();
); }
// and finally, when your program wants to exit // and finally, when your program wants to exit
} catch (Exception e) { } catch (Exception e) {
@@ -129,22 +112,20 @@ public class SocketServer extends WebSocketServer {
this.onPacketReceived(webSocket, reconstructedPacket); this.onPacketReceived(webSocket, reconstructedPacket);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
logger.exception(e); logger.exception(e);
this.log(webSocket, "Error on processing incoming package: " + e.getMessage()); this.log("Error on processing incoming package: " + e.getMessage(), webSocket);
} }
} }
@Override @Override
public void onError(WebSocket webSocket, Exception e) { public void onError(WebSocket webSocket, Exception e) {
if (webSocket != null) {
log(webSocket, e.getMessage());
webSocket.close();
}
logger.exception(e); logger.exception(e);
log(e.getMessage(), webSocket);
webSocket.close();
} }
@Override @Override
public void onStart() { public void onStart() {
logger.success("Websocket server started on port " + this.getPort()); logger.info("Websocket server started on port " + this.getPort());
} }
/** /**
@@ -152,7 +133,8 @@ public class SocketServer extends WebSocketServer {
*/ */
public void sendMessage(WebSocket webSocket, String text) { public void sendMessage(WebSocket webSocket, String text) {
try { try {
MessagePacket message = MessagePacket.create(text); MessagePacket message = new MessagePacket();
message.message = text;
webSocket.send(PacketContainer.serialize(message)); webSocket.send(PacketContainer.serialize(message));
} catch (Exception e) { } catch (Exception e) {
System.err.println("Failed to send message: " + text); System.err.println("Failed to send message: " + text);
@@ -163,13 +145,14 @@ public class SocketServer extends WebSocketServer {
/** /**
* A shorthand method for sending error messages to the client * A shorthand method for sending error messages to the client
*/ */
public void sendError(WebSocket webSocket, String text, boolean isFatal) { public void sendError(WebSocket webSocket, String text) {
try { try {
ErrorPacket error = ErrorPacket.create(text, isFatal); ErrorPacket error = new ErrorPacket();
error.error = text;
webSocket.send(PacketContainer.serialize(error)); webSocket.send(PacketContainer.serialize(error));
} catch (Exception e) { } catch (Exception e) {
logger.exception(e); logger.exception(e);
log(webSocket, "Failed to send error: " + text); log("Failed to send error: " + text, webSocket);
} }
} }
@@ -179,15 +162,16 @@ public class SocketServer extends WebSocketServer {
private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException { private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException {
SocketData socketData = webSocket.getAttachment(); SocketData socketData = webSocket.getAttachment();
// limit the number of tasks per connection // limit the amount of tasks per connection
if (socketData.totalTasks.get() >= maxTasksPerSession) { final int maxTasks = 100;
sendError(webSocket, "Exceeded the maximum amount of " + maxTasksPerSession + " tasks per session", true); if (socketData.totalTasks.get() >= maxTasks) {
sendError(webSocket, "Exceeded the maximum amount of " + maxTasks + " tasks per session");
webSocket.close(); webSocket.close();
return; return;
} }
// only allow packets that are meant to be handled by the server // only allow packets, that are meant to be handled by the server
if (!(packet instanceof IClientToServerPacket<?> clientToServerPacket)) { if (!(packet instanceof IClientToServerPacket clientToServerPacket)) {
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!"); sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
return; return;
} }
@@ -196,24 +180,22 @@ public class SocketServer extends WebSocketServer {
socketData.unhandledTasks.incrementAndGet(); socketData.unhandledTasks.incrementAndGet();
socketData.totalTasks.incrementAndGet(); socketData.totalTasks.incrementAndGet();
// add the packet to the queue so it can be started by the worker // add the packet to the queue, so it can be started by the worker
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
clientToServerPacket.onHandle(webSocket, this); clientToServerPacket.onHandle(webSocket, this);
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
if (socketData.closeIfNoTasksLeft) {
// if the websocket has 0 unhandled Tasks, close the connection // if the websocket has 0 unhandled Tasks, close the connection
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
if (remainingUnhandledTasks <= 0) { if (remainingUnhandledTasks <= 0) {
sendMessage(webSocket, "All requested tasks finished! Closing connection..."); sendMessage(webSocket, "All requested tasks finished! Closing connection...");
webSocket.close(); webSocket.close();
} }
} });
}, taskExecutor);
} }
public void log(WebSocket webSocket, String msg) { public void log(String msg, WebSocket webSocket) {
String socketId = (webSocket == null) ? "???" : webSocket.<SocketData>getAttachment().id; SocketData socketData = webSocket == null ? new SocketData("???") : webSocket.getAttachment();
logger.info("[" + socketId + "] " + msg); logger.info("["+socketData.id+"] " + msg);
} }
/** /**
@@ -225,11 +207,9 @@ public class SocketServer extends WebSocketServer {
public final String id; public final String id;
public final AtomicInteger unhandledTasks = new AtomicInteger(0); public final AtomicInteger unhandledTasks = new AtomicInteger(0);
public final AtomicInteger totalTasks = new AtomicInteger(0); public final AtomicInteger totalTasks = new AtomicInteger(0);
public boolean closeIfNoTasksLeft = false;
public SocketData(WebSocket webSocket) { public SocketData(String id) {
this.id = UUID.randomUUID().toString(); this.id = id;
webSocket.setAttachment(this);
} }
} }
} }

View File

@@ -2,7 +2,6 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode; import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
@@ -11,7 +10,7 @@ import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
public class DebugPacket implements IClientToServerPacket.Void, IServerToClientPacket { public class DebugPacket implements IClientToServerPacket, IServerToClientPacket {
public SerialUUID a1; public SerialUUID a1;
public SerialUUID a2; public SerialUUID a2;
@@ -23,13 +22,9 @@ public class DebugPacket implements IClientToServerPacket.Void, IServerToClientP
public SerialValue<?> d2; public SerialValue<?> d2;
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {} public void onHandle(WebSocket webSocket, SocketClient socketServer) {}
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {} public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
} }

View File

@@ -2,17 +2,16 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
/** /**
* A packet to send simple error messages between the client and the server * A packet to send simple error messages between the client and the server
*/ */
public class ErrorPacket implements IServerToClientPacket { public class ErrorPacket implements IClientToServerPacket, IServerToClientPacket {
/** /**
* The error endpoint for messages from the server that should be logged out as errors and possibly abort the process * The error endpoint for messages from the server, that should be logged out outputted
*/ */
public String error; public String error;
public boolean isFatal; public boolean isFatal;
@@ -28,9 +27,15 @@ public class ErrorPacket implements IServerToClientPacket {
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) { public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.exception(new RuntimeException(this.error)); SocketClient.logger.error("SocketError: " + this.error);
if (this.isFatal) { if (this.isFatal) {
socketClient.close(1, "Received fatal error from server"); throw new RuntimeException("Received fatal error from server: " + this.error);
} }
} }
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log("SocketError: " + this.error, webSocket);
}
} }

View File

@@ -1,26 +1,12 @@
package de.dhbwstuttgart.server.packet; package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
/** public interface IClientToServerPacket extends IPacket {
* A packet that will be sent to the server. Use <code>Void</code> Sub-Interface for packets without response
*
* @param <T> The response packet that will fulfill the future.
*/
public interface IClientToServerPacket<T extends IServerToClientPacket> extends IPacket {
@JsonIgnore @JsonIgnore
void onHandle(WebSocket webSocket, SocketServer socketServer); void onHandle(WebSocket webSocket, SocketServer socketServer);
@JsonIgnore
SocketFuture<T> getFuture();
/**
* Special case, where the packet will remain unanswered by the server
*/
interface Void extends IClientToServerPacket<IServerToClientPacket> {}
} }

View File

@@ -2,14 +2,13 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
/** /**
* A fallback packet that is generated if the received JSON could not be mapped to an existing package * A fallback packet that is generated, if the received json could not be mapped to an existing package
*/ */
public class InvalidPacket implements IClientToServerPacket.Void, IServerToClientPacket { public class InvalidPacket implements IClientToServerPacket, IServerToClientPacket {
/** /**
* If available, the error that caused this package to appear * If available, the error that caused this package to appear
@@ -19,17 +18,12 @@ public class InvalidPacket implements IClientToServerPacket.Void, IServerToClien
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) { public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.error("InvalidPacket: " + this.error); System.err.println("[socket] " + "InvalidPacket: " + this.error);
} }
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) { public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, "InvalidPacket: " + this.error); socketServer.log("InvalidPacket: " + this.error, webSocket);
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
} }
} }

View File

@@ -2,17 +2,16 @@ package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
/** /**
* A packet to send simple informational messages between the client and the server * A packet to send simple informational messages between the client and the server
*/ */
public class MessagePacket implements IClientToServerPacket.Void, IServerToClientPacket { public class MessagePacket implements IClientToServerPacket, IServerToClientPacket {
/** /**
* The informational message from the server that should be logged out outputted * The informational message from the server, that should be logged out outputted
*/ */
public String message; public String message;
@@ -30,11 +29,7 @@ public class MessagePacket implements IClientToServerPacket.Void, IServerToClien
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) { public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, this.message); socketServer.log(this.message, webSocket);
} }
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
} }

View File

@@ -25,14 +25,13 @@ public class PacketContainer {
public UnifyRequestPacket unifyRequestPacket = null; public UnifyRequestPacket unifyRequestPacket = null;
public UnifyResultPacket unifyResultPacket = null; public UnifyResultPacket unifyResultPacket = null;
public DebugPacket debugPacket = null; public DebugPacket debugPacket = null;
public SetAutoclosePacket setAutoclosePacket = null;
/** /**
* Generate the JSON string for the given packet * Generate the JSON string for the given packet
* *
* @param packet The packet to serialize * @param packet The packet to serialize
* @return The JSON representation of the packet * @return The json representation of the packet
*/ */
public static String serialize(IPacket packet) throws JsonProcessingException { public static String serialize(IPacket packet) throws JsonProcessingException {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@@ -48,11 +47,7 @@ public class PacketContainer {
container.unifyResultPacket = (UnifyResultPacket) packet; container.unifyResultPacket = (UnifyResultPacket) packet;
else if (packet instanceof DebugPacket) else if (packet instanceof DebugPacket)
container.debugPacket = (DebugPacket) packet; container.debugPacket = (DebugPacket) packet;
else if (packet instanceof SetAutoclosePacket)
container.setAutoclosePacket = (SetAutoclosePacket) packet;
// Add new packets here and in the deserialize method // Add new packets here and in the deserialize method
else
throw new RuntimeException("Cannot map packet to any known packet class");
return objectMapper.writeValueAsString(container); return objectMapper.writeValueAsString(container);
} }
@@ -81,8 +76,6 @@ public class PacketContainer {
return container.unifyResultPacket; return container.unifyResultPacket;
if (container.debugPacket != null) if (container.debugPacket != null)
return container.debugPacket; return container.debugPacket;
if (container.setAutoclosePacket != null)
return container.setAutoclosePacket;
// Add new packets here and in the serialize method // Add new packets here and in the serialize method
throw new RuntimeException("Cannot map received json to any known packet class"); throw new RuntimeException("Cannot map received json to any known packet class");

View File

@@ -1,32 +0,0 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* Normally, a connection stays open until either the client or the server process ends.
* Send this packet to inform the server that the connection can be closed once all tasks are done
*/
public class SetAutoclosePacket implements IClientToServerPacket.Void {
public int dummyProperty = 1;
@JsonIgnore
public static SetAutoclosePacket create() {
return new SetAutoclosePacket();
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
webSocket.<SocketServer.SocketData>getAttachment().closeIfNoTasksLeft = true;
socketServer.log(webSocket, "Marked connection as autoclose");
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}

View File

@@ -1,9 +1,6 @@
package de.dhbwstuttgart.server.packet; package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.server.ServerTaskLogger;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer; import de.dhbwstuttgart.server.SocketServer;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage; import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
@@ -23,16 +20,18 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
/** /**
* A packet to send all required data for the unification algorithm to the server and request the unification * A packet to send all required data for the unification algorithm to the server and request the unification
*/ */
public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPacket> { public class UnifyRequestPacket implements IClientToServerPacket {
public SerialMap finiteClosure; public SerialMap finiteClosure;
public SerialMap constraintSet; public SerialMap constraintSet;
@@ -40,33 +39,30 @@ public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPack
public SerialMap serialKeyStorage; public SerialMap serialKeyStorage;
public SerialValue<?> placeholders; public SerialValue<?> placeholders;
public SerialList<SerialMap> factoryplaceholders; public SerialList<SerialMap> factoryplaceholders;
public String futureId;
public int logLevel;
@JsonIgnore @JsonIgnore
private KeyStorage keyStorage = new KeyStorage(); private KeyStorage keyStorage = new KeyStorage();
@JsonIgnore @JsonIgnore
private boolean keyStorageLoaded = false; private boolean keyStorageLoaded = false;
public static UnifyRequestPacket create( public UnifyRequestPacket() {}
public UnifyRequestPacket(
FiniteClosure finiteClosure, FiniteClosure finiteClosure,
ConstraintSet<Pair> constraintSet, ConstraintSet<Pair> constraintSet,
ConstraintSet<UnifyPair> unifyConstraintSet, ConstraintSet<UnifyPair> unifyConstraintSet,
PlaceholderRegistry placeholderRegistry PlaceholderRegistry placeholderRegistry
) { ) {
UnifyRequestPacket packet = new UnifyRequestPacket(); // store contraint and finite closure
// store constraint and finite closure this.finiteClosure = finiteClosure.toSerial(keyStorage);
packet.finiteClosure = finiteClosure.toSerial(packet.keyStorage); this.constraintSet = constraintSet.toSerial(keyStorage);
packet.constraintSet = constraintSet.toSerial(packet.keyStorage); this.unifyConstraintSet = unifyConstraintSet.toSerial(keyStorage);
packet.unifyConstraintSet = unifyConstraintSet.toSerial(packet.keyStorage);
// store placeholder registry // store placeholder registry
var serialRegistry = placeholderRegistry.toSerial(packet.keyStorage); var serialRegistry = placeholderRegistry.toSerial(keyStorage);
packet.placeholders = serialRegistry.getValue("ph"); this.placeholders = serialRegistry.getValue("ph");
packet.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps(); this.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
// store referenced objects separately // store referenced objects separately
packet.serialKeyStorage = packet.keyStorage.toSerial(packet.keyStorage); this.serialKeyStorage = keyStorage.toSerial(keyStorage);
packet.logLevel = ConsoleInterface.logLevel.getValue();
return packet;
} }
@@ -99,22 +95,15 @@ public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPack
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) { public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything..."); socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
socketServer.log(webSocket, "Client requested a unification. Starting now..."); SocketServer.logger.info("Client " + webSocket.<SocketServer.SocketData>getAttachment().id + " requested a unification. Starting now...");
try { try {
var placeholderRegistry = new PlaceholderRegistry(); var placeholderRegistry = new PlaceholderRegistry();
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class); ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder); existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
Logger logger = new ServerTaskLogger( var unifyContext = new UnifyContext(Logger.NULL_LOGGER, true,
webSocket, new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), Logger.NULL_LOGGER, placeholderRegistry)),
socketServer,
Logger.LogLevel.fromValue(
Math.max(this.logLevel, Logger.LogLevel.INFO.getValue())
)
);
var unifyContext = new UnifyContext(logger, true,
new UnifyResultModel(new ConstraintSet<>(), new FiniteClosure(new HashSet<>(), logger, placeholderRegistry)),
new UnifyTaskModel(), ForkJoinPool.commonPool(), placeholderRegistry new UnifyTaskModel(), ForkJoinPool.commonPool(), placeholderRegistry
); );
@@ -141,24 +130,17 @@ public class UnifyRequestPacket implements IClientToServerPacket<UnifyResultPack
var resultSets = resultListener.getResults(); var resultSets = resultListener.getResults();
socketServer.log(webSocket, "Finished unification"); SocketServer.logger.info("Finished unification for client " + webSocket.<SocketServer.SocketData>getAttachment().id);
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets"); socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
if (webSocket.isOpen()) { if (webSocket.isOpen()) {
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets, futureId); UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets);
webSocket.send(PacketContainer.serialize(resultPacket)); webSocket.send(PacketContainer.serialize(resultPacket));
} }
} catch (Exception e) { } catch (Exception e) {
SocketServer.logger.exception(e); SocketServer.logger.exception(e);
socketServer.log(webSocket, e.getMessage()); socketServer.log(e.getMessage(), webSocket);
} }
} }
@JsonIgnore
public SocketFuture<UnifyResultPacket> getFuture() {
var future = new SocketFuture<>(List.of(UnifyResultPacket.class));
futureId = future.futureId;
return future;
}
} }

View File

@@ -18,14 +18,12 @@ public class UnifyResultPacket implements IServerToClientPacket {
public SerialList<ISerialNode> results; public SerialList<ISerialNode> results;
public SerialMap keyStorage; public SerialMap keyStorage;
public String futureId;
public static UnifyResultPacket create(List<ResultSet> resultSets, String futureId) { public static UnifyResultPacket create(List<ResultSet> resultSets) {
UnifyResultPacket serialized = new UnifyResultPacket(); UnifyResultPacket serialized = new UnifyResultPacket();
KeyStorage keyStorage = new KeyStorage(); KeyStorage keyStorage = new KeyStorage();
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage)); serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
serialized.keyStorage = keyStorage.toSerial(keyStorage); serialized.keyStorage = keyStorage.toSerial(keyStorage);
serialized.futureId = futureId;
return serialized; return serialized;
} }
@@ -37,8 +35,8 @@ public class UnifyResultPacket implements IServerToClientPacket {
@JsonIgnore @JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) { public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.info("Received unify result"); SocketClient.logger.info("[socket] Received unify result");
socketClient.completeResponseFuture(futureId, this); socketClient.setUnifyResultSets(this);
} }

View File

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
@@ -15,7 +16,6 @@ import de.dhbwstuttgart.target.tree.type.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@@ -219,22 +219,6 @@ public class StatementToTargetExpression implements ASTVisitor {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) { if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!"); if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
var thisMethod = converter.findMethod(receiverClass, methodCall.name, signature); var thisMethod = converter.findMethod(receiverClass, methodCall.name, signature);
if (thisMethod.isEmpty()) {
Target.logger.error("Expected: " + receiverClass.getClassName() + "." + methodCall.name + "(" +
signature.stream().map(TargetType::toSignature).collect(Collectors.joining())+ ")" );
AtomicBoolean hasM = new AtomicBoolean(false);
receiverClass.getMethods().forEach(m -> {
if (Objects.equals(m.getName(), methodCall.name)) {
hasM.set(true);
Target.logger.error("But only has: " + m.name + "(" +
m.getParameterList().getFormalparalist().stream().map(t -> t.getType().toString()).collect(Collectors.joining())+ ")" );
}
});
if (!hasM.get())
Target.logger.error("But does not contain method at all");
}
ClassOrInterface finalReceiverClass = receiverClass; ClassOrInterface finalReceiverClass = receiverClass;
foundMethod = thisMethod.orElseGet(() -> findMethod(finalReceiverClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow()); foundMethod = thisMethod.orElseGet(() -> findMethod(finalReceiverClass.getSuperClass().getName(), methodCall.name, signature).orElseThrow());
} else if (!isFunNType) { } else if (!isFunNType) {

View File

@@ -37,10 +37,6 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
super(); super();
} }
public Constraint(int initialCapacity) {
super(initialCapacity);
}
public Constraint(boolean isInherited, boolean isImplemented) { public Constraint(boolean isInherited, boolean isImplemented) {
this.isInherited = isInherited; this.isInherited = isInherited;
this.isImplemented = isImplemented; this.isImplemented = isImplemented;
@@ -81,14 +77,6 @@ public class Constraint<A extends IConstraintElement> extends HashSet<A> impleme
methodSignatureConstraint = c; methodSignatureConstraint = c;
} }
public <B extends IConstraintElement> Constraint<B> createdMapped(Function<A,B> mapper) {
Constraint<B> result = new Constraint<>(this.size());
for (A element : this) {
result.add(mapper.apply(element));
}
return result;
}
public String toString() { public String toString() {
return super.toString() + "\nisInherited = " + isInherited return super.toString() + "\nisInherited = " + isInherited
+ " isOveridden = " + isImplemented + " isOveridden = " + isImplemented

View File

@@ -5,7 +5,6 @@ import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage; import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.util.ArrayList; import java.util.ArrayList;
@@ -30,7 +29,7 @@ public class ResultSet implements ISerializableData {
public ResultSet(Set<ResultPair> set) { public ResultSet(Set<ResultPair> set) {
this.results = set; this.results = set;
this.genIns = TypeUnifyTaskHelper.getPresizedHashSet(results.size()); this.genIns = new HashSet<>();
results.forEach(x -> { results.forEach(x -> {
if (x instanceof PairTPHsmallerTPH) { if (x instanceof PairTPHsmallerTPH) {
this.genIns.add(x); this.genIns.add(x);

View File

@@ -14,7 +14,6 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.util.BiRelation; import de.dhbwstuttgart.util.BiRelation;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@@ -34,7 +33,7 @@ public class TYPE {
public ConstraintSet getConstraints() { public ConstraintSet getConstraints() {
ConstraintSet ret = new ConstraintSet(); ConstraintSet ret = new ConstraintSet();
for (ClassOrInterface cl : sf.KlassenVektor) { for (ClassOrInterface cl : sf.KlassenVektor) {
Set<ClassOrInterface> allClasses = TypeUnifyTaskHelper.getPresizedHashSet(allAvailableClasses.size() + sf.availableClasses.size()); var allClasses = new HashSet<ClassOrInterface>();
allClasses.addAll(allAvailableClasses); allClasses.addAll(allAvailableClasses);
allClasses.addAll(sf.availableClasses); allClasses.addAll(sf.availableClasses);
ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses))); ret.addAll(getConstraintsClass(cl, new TypeInferenceInformation(allClasses)));

View File

@@ -2,7 +2,6 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry; import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -118,18 +117,17 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
List<FieldAssumption> fieldAssumptions = info.getFields(fieldVar.fieldVarName); Set<Constraint> oderConstraints = new HashSet<>();
Set<Constraint> oderConstraints = TypeUnifyTaskHelper.getPresizedHashSet(fieldAssumptions.size());
for (FieldAssumption fieldAssumption : fieldAssumptions) { for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT, loc(fieldVar.getOffset()))); // PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT, loc(fieldVar.getOffset()))); // PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten
constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT, loc(fieldVar.getOffset()))); constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT, loc(fieldVar.getOffset())));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (oderConstraints.isEmpty()) if (oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
} }
@@ -144,7 +142,7 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(ForEachStmt forEachStmt) { public void visit(ForEachStmt forEachStmt) {
var iterableType = new RefType(ASTFactory.createClass(java.lang.Iterable.class).getClassName(), List.of(new ExtendsWildcardType(forEachStmt.statement.getType(), new NullToken())), new NullToken()); var iterableType = new RefType(ASTFactory.createClass(java.lang.Iterable.class).getClassName(), Arrays.asList(new ExtendsWildcardType(forEachStmt.statement.getType(), new NullToken())), new NullToken());
constraintsSet.addUndConstraint(new Pair(forEachStmt.expression.getType(), iterableType, PairOperator.SMALLERDOT, loc(forEachStmt.getOffset()))); constraintsSet.addUndConstraint(new Pair(forEachStmt.expression.getType(), iterableType, PairOperator.SMALLERDOT, loc(forEachStmt.getOffset())));
forEachStmt.statement.accept(this); forEachStmt.statement.accept(this);
forEachStmt.expression.accept(this); forEachStmt.expression.accept(this);
@@ -192,7 +190,7 @@ public class TYPEStmt implements StatementVisitor {
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
// Overloading: // Overloading:
Set<Constraint<Pair>> methodConstraints = new HashSet<>(); Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for (MethodAssumption m : TYPEStmt.getMethods(methodCall.name, methodCall.arglist, info)) { for (MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)) {
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver); Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
methodConstraints.addAll(oneMethodConstraints); methodConstraints.addAll(oneMethodConstraints);
@@ -202,7 +200,7 @@ public class TYPEStmt implements StatementVisitor {
* oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint); extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint); methodConstraints.add(extendsOneMethodConstraint); * oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint); extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint); methodConstraints.add(extendsOneMethodConstraint);
*/ */
} }
if (methodConstraints.isEmpty()) { if (methodConstraints.size() < 1) {
throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset()); throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
@@ -215,7 +213,7 @@ public class TYPEStmt implements StatementVisitor {
for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) { for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) {
methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance())); methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance()));
} }
if (methodConstraints.isEmpty()) { if (methodConstraints.size() < 1) {
throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset()); throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
@@ -285,13 +283,8 @@ public class TYPEStmt implements StatementVisitor {
// see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17 // see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
// Expression muss zu Numeric Convertierbar sein. also von Numeric erben // Expression muss zu Numeric Convertierbar sein. also von Numeric erben
Constraint<Pair> numeric; Constraint<Pair> numeric;
HashSet<JavaClassName> classNames = TypeUnifyTaskHelper.getPresizedHashSet(info.getAvailableClasses().size());
for (var classEl : info.getAvailableClasses()) {
classNames.add(classEl.getClassName());
}
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(bytee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -299,7 +292,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(shortt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -307,7 +300,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(integer.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -315,7 +308,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(longg.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -323,7 +316,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(floatt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -331,7 +324,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
// PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (classNames.contains(doublee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset()))); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT, loc(binary.getOffset())));
@@ -346,7 +339,7 @@ public class TYPEStmt implements StatementVisitor {
if (binary.operation.equals(BinaryExpr.Operator.ADD)) { if (binary.operation.equals(BinaryExpr.Operator.ADD)) {
// Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2) // Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
if (classNames.contains(string.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
Constraint<Pair> stringConcat = new Constraint<>(); Constraint<Pair> stringConcat = new Constraint<>();
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset()))); stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset())));
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset()))); stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT, loc(binary.getOffset())));
@@ -354,7 +347,7 @@ public class TYPEStmt implements StatementVisitor {
numericAdditionOrStringConcatenation.add(stringConcat); numericAdditionOrStringConcatenation.add(stringConcat);
} }
} }
if (numericAdditionOrStringConcatenation.isEmpty()) { if (numericAdditionOrStringConcatenation.size() < 1) {
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset()); throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
} }
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
@@ -740,7 +733,7 @@ public class TYPEStmt implements StatementVisitor {
} }
// 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(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
return ret; return ret;
} }
@@ -753,8 +746,8 @@ public class TYPEStmt implements StatementVisitor {
// funNParams.add(TypePlaceholder.fresh(new NullToken())); // funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(), new NullToken())); funNParams.add(new GenericRefType(NameGenerator.makeNewName(), new NullToken()));
} }
funNParams.getLast(); funNParams.get(funNParams.size() - 1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.getLast(), funNParams.subList(0, funNParams.size() - 1), new TypeScope() { ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size() - 1), funNParams.subList(0, funNParams.size() - 1), new TypeScope() {
@Override @Override
public Iterable<? extends GenericTypeVar> getGenerics() { public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException(); throw new NotImplementedException();
@@ -890,9 +883,13 @@ public class TYPEStmt implements StatementVisitor {
child.getLabels().forEach(el -> { child.getLabels().forEach(el -> {
if (el.getType() instanceof RefType) { if (el.getType() instanceof RefType) {
if (el.getPattern() instanceof RecordPattern pattern) { var recType = el;
if (el.getPattern() instanceof RecordPattern) {
var pattern = (RecordPattern) recType.getPattern();
recursivelyAddRecordConstraints(pattern); recursivelyAddRecordConstraints(pattern);
} }
} }
}); });
@@ -908,7 +905,7 @@ public class TYPEStmt implements StatementVisitor {
var allClasses = info.getAvailableClasses(); var allClasses = info.getAvailableClasses();
var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) pattern.getType()).getName())).toList(); var interestingClasses = allClasses.stream().filter(as -> as.getClassName().equals(((RefType) pattern.getType()).getName())).toList();
var constructors = interestingClasses.getFirst().getConstructors(); var constructors = interestingClasses.get(0).getConstructors();
int counter = 0; int counter = 0;

View File

@@ -1,7 +1,6 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.RecursiveTask; import java.util.concurrent.RecursiveTask;
@@ -9,7 +8,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* An intermediate class for the recursive steps of the TypeUnifyTask: * An intermediate class for the recursive steps of the TypeUnifyTask:
* This allows canceling parts of the recursion tree, instead of only the whole execution as before. But in * This allows to cancel parts of the recursion tree, instead of only the whole execution as before. But in
* order for that to work, all cancellable child tasks must be added when they are created * order for that to work, all cancellable child tasks must be added when they are created
* *
* @param <T> * @param <T>
@@ -17,19 +16,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
public abstract class CancellableTask<T> extends RecursiveTask<T> { public abstract class CancellableTask<T> extends RecursiveTask<T> {
private final AtomicBoolean executionCancelled = new AtomicBoolean(false); private final AtomicBoolean executionCancelled = new AtomicBoolean(false);
private final List<CancellableTask<?>> childTasks = new LinkedList<>(); private final List<CancellableTask<?>> childTasks = new ArrayList<>();
private CancellableTask<?> parentTask = null; private CancellableTask<?> parentTask = null;
/** /**
* Set the execution for this task and all its (recursive) children to be canceled * Set the execution for this task and all its (recursive) children to be cancelled
*/ */
protected void cancelExecution() { protected void cancelExecution() {
// is this branch already canceled? Then do nothing // is this branch already cancelled? Then do nothing
if (this.executionCancelled.getAndSet(true)) return; if (this.executionCancelled.get()) return;
executionCancelled.set(true);
this.cancelChildExecution(); this.cancelChildExecution();
} }
private void cancelChildExecution() { public void cancelChildExecution() {
synchronized (this.childTasks) { synchronized (this.childTasks) {
for (var childTask : childTasks) { for (var childTask : childTasks) {
// no need to cancel a branch that is already finished // no need to cancel a branch that is already finished
@@ -40,24 +40,6 @@ public abstract class CancellableTask<T> extends RecursiveTask<T> {
} }
} }
private void cancelChildExecutionAfter(CancellableTask<?> checkpointTask) {
boolean reachedCheckpoint = false;
int i = 0;
for (var childTask : childTasks) {
if (!reachedCheckpoint) {
reachedCheckpoint = childTask == checkpointTask;
}
else {
// no need to cancel a branch that is already finished
if (!childTask.isDone()) {
childTask.cancelExecution();
}
i++;
}
}
System.out.println("Skipped " + i + " younger siblings");
}
protected void cancelSiblingTasks() { protected void cancelSiblingTasks() {
if (this.parentTask != null) { if (this.parentTask != null) {
boolean thisWasCancelledBefore = this.executionCancelled.get(); boolean thisWasCancelledBefore = this.executionCancelled.get();
@@ -66,12 +48,6 @@ public abstract class CancellableTask<T> extends RecursiveTask<T> {
} }
} }
public void cancelYoungerSiblingTasks() {
if (this.parentTask != null) {
this.parentTask.cancelChildExecutionAfter(this);
}
}
public Boolean isExecutionCancelled() { public Boolean isExecutionCancelled() {
return executionCancelled.get(); return executionCancelled.get();
} }
@@ -79,9 +55,6 @@ public abstract class CancellableTask<T> extends RecursiveTask<T> {
public void addChildTask(CancellableTask<?> childTask) { public void addChildTask(CancellableTask<?> childTask) {
this.childTasks.add(childTask); this.childTasks.add(childTask);
childTask.setParentTask(this); childTask.setParentTask(this);
if (this.executionCancelled.get()) {
childTask.executionCancelled.set(true);
}
} }
private void setParentTask(CancellableTask<?> parentTask) { private void setParentTask(CancellableTask<?> parentTask) {

View File

@@ -95,7 +95,7 @@ public class MartelliMontanariUnify implements IUnify {
if(lhsType instanceof PlaceholderType) { if(lhsType instanceof PlaceholderType) {
mgu.add((PlaceholderType) lhsType, rhsType); mgu.add((PlaceholderType) lhsType, rhsType);
//PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen. //PL 2018-04-01 nach checken, ob es richtig ist, dass keine Substitutionen uebergeben werden muessen.
termsList.replaceAll(mgu::apply); termsList = termsList.stream().map(x -> mgu.apply(x)).collect(Collectors.toCollection(ArrayList::new));
idx = idx+1 == termsList.size() ? 0 : idx+1; idx = idx+1 == termsList.size() ? 0 : idx+1;
continue; continue;
} }

View File

@@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Optional; import java.util.Optional;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
@@ -649,11 +648,9 @@ public class RuleSet implements IRuleSet{
@Override @Override
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints) { public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Constraint<UnifyPair>>> oderConstraints) {
// Statistically, typeMap will fill up quickly and resize multiple times. To reduce this, we start with a higher capacity HashMap<UnifyType, Integer> typeMap = new HashMap<>();
HashMap<UnifyType, Integer> typeMap = new HashMap<>(200);
Stack<UnifyType> occuringTypes = new Stack<>(); Stack<UnifyType> occuringTypes = new Stack<>();
occuringTypes.ensureCapacity(pairs.size() * 3);
for(UnifyPair pair : pairs) { for(UnifyPair pair : pairs) {
occuringTypes.push(pair.getLhsType()); occuringTypes.push(pair.getLhsType());
@@ -671,9 +668,9 @@ public class RuleSet implements IRuleSet{
if(t1 instanceof SuperType) if(t1 instanceof SuperType)
occuringTypes.push(((SuperType) t1).getSuperedType()); occuringTypes.push(((SuperType) t1).getSuperedType());
else else
t1.getTypeParams().forEach(occuringTypes::push); t1.getTypeParams().forEach(x -> occuringTypes.push(x));
} }
LinkedList<UnifyPair> result1 = new LinkedList<UnifyPair>(pairs); Queue<UnifyPair> result1 = new LinkedList<UnifyPair>(pairs);
ArrayList<UnifyPair> result = new ArrayList<UnifyPair>(); ArrayList<UnifyPair> result = new ArrayList<UnifyPair>();
boolean applied = false; boolean applied = false;
@@ -694,30 +691,19 @@ public class RuleSet implements IRuleSet{
&& !((rhsType instanceof WildcardType) && ((WildcardType)rhsType).getWildcardedType().equals(lhsType))) //PL eigefuegt 2018-02-18 && !((rhsType instanceof WildcardType) && ((WildcardType)rhsType).getWildcardedType().equals(lhsType))) //PL eigefuegt 2018-02-18
{ {
Unifier uni = new Unifier(lhsType, rhsType); Unifier uni = new Unifier(lhsType, rhsType);
// apply unifier to result and result1 in place result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
result.replaceAll(p -> uni.apply(pair, p)); result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
ListIterator<UnifyPair> result1Iterator = result1.listIterator();
while (result1Iterator.hasNext()) {
UnifyPair x = result1Iterator.next();
result1Iterator.set(uni.apply(pair, x));
}
Function<? super Constraint<UnifyPair>,? extends Constraint<UnifyPair>> applyUni = b -> b.stream().map( Function<? super Constraint<UnifyPair>,? extends Constraint<UnifyPair>> applyUni = b -> b.stream().map(
x -> uni.apply(pair,x)).collect(Collectors.toCollection((b.getExtendConstraint() != null) x -> uni.apply(pair,x)).collect(Collectors.toCollection((b.getExtendConstraint() != null)
? () -> new Constraint<UnifyPair>( ? () -> new Constraint<UnifyPair>(
b.isInherited(), b.isInherited(),
b.isImplemented(), b.isImplemented(),
b.getExtendConstraint().createdMapped(x -> uni.apply(pair,x)), b.getExtendConstraint().stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(Constraint::new)),
b.getmethodSignatureConstraint().stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new))) b.getmethodSignatureConstraint().stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new)))
: () -> new Constraint<UnifyPair>(b.isInherited(), b.isImplemented()) : () -> new Constraint<UnifyPair>(b.isInherited(), b.isImplemented())
)); ));
oderConstraints.replaceAll(oc -> { oderConstraints.replaceAll(oc -> oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new)));
HashSet<Constraint<UnifyPair>> mapped = new HashSet<>(oc.size());
for (var element : oc) {
mapped.add(applyUni.apply(element));
}
return mapped;
});
/* /*
oderConstraints = oderConstraints.stream().map( oderConstraints = oderConstraints.stream().map(
a -> a.stream().map(applyUni a -> a.stream().map(applyUni

View File

@@ -45,7 +45,7 @@ public class TypeUnify2Task extends TypeUnifyTask {
*/ */
//writeLog("xxx"); //writeLog("xxx");
//noOfThread--; //noOfThread--;
if (this.isExecutionCancelled()) { if (this.myIsCancelled()) {
return CompletableFuture.completedFuture(new HashSet<>()); return CompletableFuture.completedFuture(new HashSet<>());
} else { } else {
return res; return res;

View File

@@ -3,7 +3,6 @@ package de.dhbwstuttgart.typeinference.unify;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.server.ServerTaskLogger;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.cartesianproduct.VarianceCase; import de.dhbwstuttgart.typeinference.unify.cartesianproduct.VarianceCase;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
@@ -27,7 +26,11 @@ import de.dhbwstuttgart.typeinference.unify.model.WildcardType;
import de.dhbwstuttgart.util.Logger; 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.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serial; import java.io.Serial;
import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@@ -46,6 +49,7 @@ import java.util.concurrent.RecursiveTask;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.io.output.NullOutputStream;
/** /**
@@ -113,6 +117,8 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
public static int noShortendElements; public static int noShortendElements;
public static int noou = 0; public static int noou = 0;
boolean myIsCanceled = false;
public TypeUnifyTask(UnifyContext context) { public TypeUnifyTask(UnifyContext context) {
this.context = context.newWithLogger(Logger.NULL_LOGGER); this.context = context.newWithLogger(Logger.NULL_LOGGER);
rules = new RuleSet(context.placeholderRegistry()); rules = new RuleSet(context.placeholderRegistry());
@@ -149,7 +155,7 @@ 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 = (context.logger() instanceof ServerTaskLogger) ? context : context.newWithLogger( this.context = context.newWithLogger(
Logger.forFile( Logger.forFile(
System.getProperty("user.dir") + "/logFiles/" + "Thread", System.getProperty("user.dir") + "/logFiles/" + "Thread",
"Unify" "Unify"
@@ -207,6 +213,13 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
} }
} }
*/ */
void myCancel(boolean b) {
myIsCanceled = true;
}
public boolean myIsCancelled() {
return myIsCanceled;
}
public CompletableFuture<Set<Set<UnifyPair>>> compute() { public CompletableFuture<Set<Set<UnifyPair>>> compute() {
if (one) { if (one) {
@@ -236,7 +249,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
throw new TypeinferenceException("Unresolved constraints: " + res, new NullToken()); //return new HashSet<>(); throw new TypeinferenceException("Unresolved constraints: " + res, new NullToken()); //return new HashSet<>();
} }
if (this.isExecutionCancelled()) { if (this.myIsCancelled()) {
return new HashSet<>(); return new HashSet<>();
} }
@@ -273,7 +286,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
//.collect(Collectors.toCollection(HashSet::new))); //.collect(Collectors.toCollection(HashSet::new)));
if (this.isExecutionCancelled()) { if (this.myIsCancelled()) {
return CompletableFuture.completedFuture(new HashSet<>()); return CompletableFuture.completedFuture(new HashSet<>());
} }
@@ -302,7 +315,14 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
/* /*
* Occurs-Check durchfuehren * Occurs-Check durchfuehren
*/ */
Set<UnifyPair> ocurrPairs = TypeUnifyTaskHelper.occursCheck(eq); Set<UnifyPair> ocurrPairs = eq.stream().filter(x -> {
UnifyType lhs, rhs;
return (lhs = x.getLhsType()) instanceof PlaceholderType
&& !((rhs = x.getRhsType()) instanceof PlaceholderType)
&& rhs.getTypeParams().occurs((PlaceholderType) lhs);
})
.peek(UnifyPair::setUndefinedPair)
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> finalOcurrPairs = ocurrPairs; Set<UnifyPair> finalOcurrPairs = ocurrPairs;
context.logger().debug(() -> "ocurrPairs: " + finalOcurrPairs); context.logger().debug(() -> "ocurrPairs: " + finalOcurrPairs);
@@ -326,7 +346,14 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
/* In commit dfd91b5f8b7fca1cb5f302eec4b0ba3330271c9b eingefuegt ANFANG */ /* In commit dfd91b5f8b7fca1cb5f302eec4b0ba3330271c9b eingefuegt ANFANG */
Set<UnifyPair> occurcheck = new HashSet<>(eq0); Set<UnifyPair> occurcheck = new HashSet<>(eq0);
occurcheck.removeAll(eq0Prime); occurcheck.removeAll(eq0Prime);
ocurrPairs = TypeUnifyTaskHelper.occursCheck(occurcheck); ocurrPairs = occurcheck.stream().filter(x -> {
UnifyType lhs, rhs;
return (lhs = x.getLhsType()) instanceof PlaceholderType
&& !((rhs = x.getRhsType()) instanceof PlaceholderType)
&& rhs.getTypeParams().occurs((PlaceholderType) lhs);
})
.peek(UnifyPair::setUndefinedPair)
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> finalOcurrPairs1 = ocurrPairs; Set<UnifyPair> finalOcurrPairs1 = ocurrPairs;
context.logger().debug(() -> "ocurrPairs: " + finalOcurrPairs1); context.logger().debug(() -> "ocurrPairs: " + finalOcurrPairs1);
if (!ocurrPairs.isEmpty()) { if (!ocurrPairs.isEmpty()) {
@@ -463,7 +490,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
// .collect(Collectors.toCollection(HashSet::new)); // .collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE //Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
if (this.isExecutionCancelled()) { if (this.myIsCancelled()) {
return CompletableFuture.completedFuture(new HashSet<>()); return CompletableFuture.completedFuture(new HashSet<>());
} }
@@ -740,8 +767,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
// Ergebnisvariable für die parallele Verabeitung: Tupel aus // Ergebnisvariable für die parallele Verabeitung: Tupel aus
// - forkOrig result : currentThreadResult (frueher "res") // - forkOrig result : currentThreadResult (frueher "res")
// - fork results : forkResults (frueher "add_res") // - fork results : forkResults (frueher "add_res")
CompletableFuture<VarianceCase.ComputationResults> parallelResultDataFuture; CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> parallelResultDataFuture;
if (parallel) { if (parallel) {
parallelResultDataFuture = varianceCase.computeParallel( parallelResultDataFuture = varianceCase.computeParallel(
@@ -752,16 +778,13 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
// same as variance = 0 // same as variance = 0
elems.add(varianceCase.a); //PL 2019-01-16 muss das wirklich hin steht schon in Zeile 859 ja braucht man siehe Zeile 859 elems.add(varianceCase.a); //PL 2019-01-16 muss das wirklich hin steht schon in Zeile 859 ja braucht man siehe Zeile 859
parallelResultDataFuture = this.unify2(elems, eq, oderConstraints, fc, false, rekTiefe, new HashSet<>(methodSignatureConstraint)) parallelResultDataFuture = this.unify2(elems, eq, oderConstraints, fc, false, rekTiefe, new HashSet<>(methodSignatureConstraint))
.thenApply(VarianceCase.ComputationResults::new); .thenApply(currentThreadResult -> new Tuple<>(currentThreadResult, new HashSet<>()));
} }
if (this.isExecutionCancelled()) {
return CompletableFuture.completedFuture(new HashSet<>());
}
return parallelResultDataFuture.thenCompose(parallelResultData -> { return parallelResultDataFuture.thenCompose(parallelResultData -> {
Set<Set<UnifyPair>> currentThreadResult = parallelResultData.mainResult; Set<Set<UnifyPair>> currentThreadResult = parallelResultData.getFirst();
Set<Set<Set<UnifyPair>>> forkResults = parallelResultData.forkResults; Set<Set<Set<UnifyPair>>> forkResults = parallelResultData.getSecond();
Set<Set<UnifyPair>> result = prevResult; Set<Set<UnifyPair>> result = prevResult;
List<Set<UnifyPair>> nextSetAsList = prevNextSetAsList; List<Set<UnifyPair>> nextSetAsList = prevNextSetAsList;
@@ -825,6 +848,17 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
if (parallel) { if (parallel) {
for (Set<Set<UnifyPair>> par_res : forkResults) { for (Set<Set<UnifyPair>> par_res : forkResults) {
if (variance == 0) {
if (!result.isEmpty() && !isUndefinedPairSetSet(currentThreadResult)) {
return CompletableFuture.completedFuture(result);
}
else {
result.addAll(par_res);
continue;
}
}
if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) { if (!isUndefinedPairSetSet(par_res) && isUndefinedPairSetSet(result)) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
result = par_res; result = par_res;
@@ -858,7 +892,7 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
// Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<>(nextSetAsList).iterator(); // Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<>(nextSetAsList).iterator();
boolean shouldBreak = varianceCase.eraseInvalidSets(rekTiefe, aParDef, nextSetAsList); boolean shouldBreak = varianceCase.eraseInvalidSets(rekTiefe, aParDef, nextSetAsList);
if (shouldBreak) { if (shouldBreak) {
// this.cancelYoungerSiblingTasks(); //this.cancelChildExecution();
return CompletableFuture.completedFuture(result); return CompletableFuture.completedFuture(result);
} }
@@ -1711,9 +1745,8 @@ public class TypeUnifyTask extends CancellableTask<CompletableFuture<Set<Set<Uni
aa.putAll(b); aa.putAll(b);
return aa; return aa;
}; };
var involvedPlaceholderTypes = x.getInvolvedPlaceholderTypes(); HashMap<PlaceholderType, PlaceholderType> hm = x.getInvolvedPlaceholderTypes().stream()
HashMap<PlaceholderType, PlaceholderType> hm = involvedPlaceholderTypes.stream() .reduce(new HashMap<PlaceholderType, PlaceholderType>(),
.reduce(TypeUnifyTaskHelper.getPresizedHashMap(involvedPlaceholderTypes.size()),
(aa, b) -> { (aa, b) -> {
aa.put(b, PlaceholderType.freshPlaceholder(context.placeholderRegistry())); aa.put(b, PlaceholderType.freshPlaceholder(context.placeholderRegistry()));
return aa; return aa;

View File

@@ -5,7 +5,6 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -186,36 +185,4 @@ public class TypeUnifyTaskHelper {
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
} }
public static Set<UnifyPair> occursCheck(final Set<UnifyPair> eq) {
Set<UnifyPair> ocurrPairs = new HashSet<>(eq.size());
for (UnifyPair x : eq) {
UnifyType lhs = x.getLhsType();
UnifyType rhs = x.getRhsType();
if (lhs instanceof PlaceholderType lhsPlaceholder &&
!(rhs instanceof PlaceholderType) &&
rhs.getTypeParams().occurs(lhsPlaceholder))
{
x.setUndefinedPair();
ocurrPairs.add(x);
}
}
return ocurrPairs;
}
public static <T> HashSet<T> getPresizedHashSet(int minElements) {
if (minElements < 16) return new HashSet<>();
// HashSet and HashMap will resize at 75% load, so we account for that by multiplying with 1.5
int n = (int)(minElements * 1.5);
return new HashSet<>(n);
}
public static <S,T> HashMap<S,T> getPresizedHashMap(int minElements) {
if (minElements < 16) return new HashMap<>();
// HashSet and HashMap will resize at 75% load, so we account for that by multiplying with 1.5
int n = (int)(minElements * 1.5);
return new HashMap<>(n);
}
} }

View File

@@ -12,7 +12,7 @@ public class UnifyTaskModel {
public synchronized void cancel() { public synchronized void cancel() {
for(TypeUnifyTask t : usedTasks) { for(TypeUnifyTask t : usedTasks) {
t.cancelExecution(); t.myCancel(true);
} }
} }
} }

View File

@@ -11,20 +11,19 @@ import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.Tuple; import de.dhbwstuttgart.util.Tuple;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class UnknownVarianceCase extends VarianceCase { public class Variance0Case extends VarianceCase {
protected final int variance = 0; protected final int variance = 0;
protected final AtomicBoolean shouldBreak = new AtomicBoolean(false); protected Variance0Case(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
protected UnknownVarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
super(isOderConstraint, typeUnifyTask, context); super(isOderConstraint, typeUnifyTask, context);
} }
@@ -52,6 +51,7 @@ public class UnknownVarianceCase extends VarianceCase {
a = nextSetAsList.removeFirst(); a = nextSetAsList.removeFirst();
} }
Set<UnifyPair> finalA = a; Set<UnifyPair> finalA = a;
if (!this.isOderConstraint && optOrigPair != null && optOrigPair.isPresent()) { if (!this.isOderConstraint && optOrigPair != null && optOrigPair.isPresent()) {
if (optOrigPair.get().getBasePair().getLhsType() instanceof PlaceholderType) { if (optOrigPair.get().getBasePair().getLhsType() instanceof PlaceholderType) {
@@ -63,20 +63,20 @@ public class UnknownVarianceCase extends VarianceCase {
nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != -1).toList() nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != -1).toList()
); );
} }
nextSetAsList.remove(a);
} else if (this.isOderConstraint) { } else if (this.isOderConstraint) {
nextSetasListRest = typeUnifyTask.oup.maxElements( nextSetasListRest = typeUnifyTask.oup.maxElements(
nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != 1).toList() nextSetAsList.stream().filter(a_next -> typeUnifyTask.oup.compare(finalA, a_next) != 1).toList()
); );
} else { } else {
nextSetasListRest = (nextSetAsList.size() > 5) ? nextSetAsList.subList(0, 5) : nextSetAsList; for (int i = 0; i < Math.min(nextSetAsList.size(), 5); i++) {
nextSetasListRest.add(nextSetAsList.removeFirst());
}
} }
nextSetAsList.removeAll(nextSetasListRest);
// */
} }
@Override @Override
public CompletableFuture<ComputationResults> computeParallel( public CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> computeParallel(
Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> elems,
Set<UnifyPair> eq, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
@@ -88,98 +88,82 @@ public class UnknownVarianceCase extends VarianceCase {
Set<Set<UnifyPair>> result, Set<Set<UnifyPair>> result,
Set<Set<UnifyPair>> aParDef Set<Set<UnifyPair>> aParDef
) { ) {
CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> resultValues = CompletableFuture.completedFuture(new Tuple<>(
new HashSet<>(), new HashSet<>()
));
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems); Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a); newElemsOrig.add(a);
Set<UnifyPair> newMethodSignatureConstraintOrig = new HashSet<>(methodSignatureConstraint);
if (isOderConstraint) { /* FORK ANFANG */
methodSignatureConstraint.addAll(((Constraint<UnifyPair>) a).getmethodSignatureConstraint()); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraint));
}
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, context, rekTiefe, newMethodSignatureConstraintOrig);
typeUnifyTask.addChildTask(forkOrig); typeUnifyTask.addChildTask(forkOrig);
// schedule compute() on another thread
CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f);
CompletableFuture<ComputationResults> resultValues = forkOrigFuture.thenApply( resultValues = resultValues.thenCombine(forkOrigFuture,
(currentThreadResult) -> { (prevResults, currentThreadResult) -> {
forkOrig.context.logger().debug("final Orig 0"); forkOrig.context.logger().debug("final Orig 0");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
return new ComputationResults(currentThreadResult); return new Tuple<>(currentThreadResult, prevResults.getSecond());
}); });
int i = 0; //forks.add(forkOrig);
Set<Set<UnifyPair>>[] additionalResults = new HashSet[nextSetasListRest.size()]; if (typeUnifyTask.myIsCancelled()) {
Constraint<UnifyPair>[] extendConstraints = new Constraint[nextSetasListRest.size()]; throw new UnifyCancelException();
while (!nextSetasListRest.isEmpty()) {
final int finalI = i++;
Set<UnifyPair> nSaL = nextSetasListRest.removeFirst();
context.logger().debug(() -> "0 RM" + nSaL.toString());
if (this.isOderConstraint) {
Constraint<UnifyPair> extendConstraint = ((Constraint<UnifyPair>) nSaL).getExtendConstraint();
extendConstraints[finalI] = extendConstraint;
} }
else if (!sameEqSet.isEmpty() && !typeUnifyTask.checkNoContradiction(nSaL, sameEqSet, result)) { /* FORK ENDE */
context.logger().debug("a in " + variance + " " + a);
context.logger().debug("nextSetasListRest: " + nextSetasListRest.toString());
while (!nextSetasListRest.isEmpty()) {
Set<UnifyPair> nSaL = nextSetasListRest.removeFirst();
nextSetAsList.remove(nSaL);
context.logger().debug("0 RM" + nSaL.toString());
if (!this.isOderConstraint) {
//ueberpruefung ob zu a =. ty \in nSaL in sameEqSet ein Widerspruch besteht
if (!sameEqSet.isEmpty() && !typeUnifyTask.checkNoContradiction(nSaL, sameEqSet, result)) {
TypeUnifyTask.noShortendElements++; TypeUnifyTask.noShortendElements++;
continue; continue;
} }
} else {
Constraint<UnifyPair> extendConstraint = ((Constraint<UnifyPair>) nSaL).getExtendConstraint();
nextSetasListOderConstraints.add(extendConstraint);
}
Set<UnifyPair> newEq = new HashSet<>(eq); Set<UnifyPair> newEq = new HashSet<>(eq);
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
Set<UnifyPair> newMethodSignatureConstraint = new HashSet<>(methodSignatureConstraint); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraint));
if (isOderConstraint) {
methodSignatureConstraint.addAll(((Constraint<UnifyPair>) nSaL).getmethodSignatureConstraint());
}
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, context, rekTiefe, newMethodSignatureConstraint);
typeUnifyTask.addChildTask(fork); typeUnifyTask.addChildTask(fork);
// schedule compute() on another thread // schedule compute() on another thread
CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f);
resultValues = resultValues.thenCombine(forkFuture, (compResult, forkResult) -> { resultValues = resultValues.thenCombine(forkFuture,
additionalResults[finalI] = forkResult; (prevResults, fork_res) -> {
context.logger().error("finalI: " + finalI); if (typeUnifyTask.myIsCancelled()) {
return compResult; throw new UnifyCancelException();
});
} }
context.logger().debug("fork_res: " + fork_res.toString());
context.logger().debug(Boolean.valueOf((typeUnifyTask.isUndefinedPairSetSet(fork_res))).toString());
prevResults.getSecond().add(fork_res);
if (!typeUnifyTask.isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement());
}
fork.context.logger().debug("final 0");
fork.closeLogFile();
return prevResults;
}
);
if (typeUnifyTask.myIsCancelled()) {
int finalI1 = i; throw new UnifyCancelException();
return resultValues.thenCompose(compResult -> {
var oldResult = compResult.mainResult;
for (int e = 0; e < finalI1; e++) {
Set<Set<UnifyPair>> currentResult = additionalResults[e];
boolean oldResultInvalid = typeUnifyTask.isUndefinedPairSetSet(oldResult);
boolean currentResultInvalid = typeUnifyTask.isUndefinedPairSetSet(currentResult);
if (!oldResult.isEmpty() && !oldResultInvalid) {
boolean shouldBreak = this.eraseInvalidSets(rekTiefe, new HashSet<>(), nextSetAsList);
if (shouldBreak) {
return CompletableFuture.completedFuture(compResult);
} }
} }
if (this.isOderConstraint) { return resultValues;
nextSetasListOderConstraints.add(extendConstraints[e]);
}
if (!currentResultInvalid && oldResultInvalid) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
oldResult = currentResult;
} else if (oldResultInvalid == currentResultInvalid || oldResult.isEmpty()) {
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
Set<Set<UnifyPair>> finalOldResult = oldResult;
context.logger().debug(() -> "RES var1 ADD:" + finalOldResult.toString() + " " + currentResult.toString());
oldResult.addAll(currentResult);
}
}
compResult.mainResult = oldResult;
return CompletableFuture.completedFuture(compResult);
});
} }
@Override @Override
@@ -202,6 +186,7 @@ public class UnknownVarianceCase extends VarianceCase {
if (!this.isOderConstraint) { if (!this.isOderConstraint) {
return true; return true;
} else { } else {
nextSetAsList.removeAll(nextSetasListOderConstraints); nextSetAsList.removeAll(nextSetasListOderConstraints);
nextSetasListOderConstraints = new ArrayList<>(); nextSetasListOderConstraints = new ArrayList<>();
context.logger().debug("Removed: " + nextSetasListOderConstraints); context.logger().debug("Removed: " + nextSetasListOderConstraints);
@@ -209,16 +194,19 @@ public class UnknownVarianceCase extends VarianceCase {
List<Set<UnifyPair>> notInherited = smallerSetasList.stream() List<Set<UnifyPair>> notInherited = smallerSetasList.stream()
.filter(x -> !((Constraint<UnifyPair>) x).isInherited()) .filter(x -> !((Constraint<UnifyPair>) x).isInherited())
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
List<Set<UnifyPair>> notErased = new ArrayList<>(); final List<Set<UnifyPair>> notErased = new ArrayList<>();
notInherited.forEach(x -> notErased.addAll(typeUnifyTask.oup.smallerEqThan(x, smallerSetasList))); notInherited.forEach(x -> notErased.addAll(typeUnifyTask.oup.smallerEqThan(x, smallerSetasList)));
List<Set<UnifyPair>> erased = new ArrayList<>(smallerSetasList); List<Set<UnifyPair>> erased = new ArrayList<>(smallerSetasList);
erased.removeAll(notErased); erased.removeAll(notErased);
nextSetAsList.removeAll(erased); nextSetAsList.removeAll(erased);
context.logger().debug("Removed: " + erased); context.logger().debug("Removed: " + erased);
context.logger().debug("Not Removed: " + nextSetAsList); context.logger().debug("Not Removed: " + nextSetAsList);
for (Set<UnifyPair> aPar : aParDef) { for (Set<UnifyPair> aPar : aParDef) {
nextSetAsList.removeAll(nextSetasListOderConstraints);
nextSetasListOderConstraints = new ArrayList<>();
context.logger().debug("Removed: " + nextSetasListOderConstraints);
smallerSetasList.clear(); smallerSetasList.clear();
smallerSetasList.addAll(typeUnifyTask.oup.smallerThan(aPar, nextSetAsList)); smallerSetasList.addAll(typeUnifyTask.oup.smallerThan(aPar, nextSetAsList));
notInherited = smallerSetasList.stream() notInherited = smallerSetasList.stream()

View File

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify.cartesianproduct; package de.dhbwstuttgart.typeinference.unify.cartesianproduct;
import de.dhbwstuttgart.exceptions.UnifyCancelException;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task; import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
@@ -16,11 +17,11 @@ import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ContravarianceCase extends VarianceCase { public class Variance1Case extends VarianceCase {
protected final int variance = 1; protected final int variance = 1;
protected ContravarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) { protected Variance1Case(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
super(isOderConstraint, typeUnifyTask, context); super(isOderConstraint, typeUnifyTask, context);
} }
@@ -36,7 +37,7 @@ public class ContravarianceCase extends VarianceCase {
if (this.isOderConstraint) { if (this.isOderConstraint) {
nextSetasListOderConstraints.add(((Constraint<UnifyPair>) a).getExtendConstraint()); nextSetasListOderConstraints.add(((Constraint<UnifyPair>) a).getExtendConstraint());
} }
context.logger().debug(() -> "nextSetasListOderConstraints 1: " + nextSetasListOderConstraints); context.logger().debug("nextSetasListOderConstraints 1: " + nextSetasListOderConstraints);
//Alle maximale Elemente in nextSetasListRest bestimmen //Alle maximale Elemente in nextSetasListRest bestimmen
//nur für diese wird parallele Berechnung angestossen. //nur für diese wird parallele Berechnung angestossen.
@@ -48,7 +49,7 @@ public class ContravarianceCase extends VarianceCase {
@Override @Override
public CompletableFuture<ComputationResults> computeParallel( public CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> computeParallel(
Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> elems,
Set<UnifyPair> eq, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
@@ -60,6 +61,10 @@ public class ContravarianceCase extends VarianceCase {
Set<Set<UnifyPair>> result, Set<Set<UnifyPair>> result,
Set<Set<UnifyPair>> aParDef Set<Set<UnifyPair>> aParDef
) { ) {
CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> resultValues = CompletableFuture.completedFuture(new Tuple<>(
new HashSet<>(), new HashSet<>()
));
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems); Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
@@ -70,16 +75,16 @@ public class ContravarianceCase extends VarianceCase {
typeUnifyTask.addChildTask(forkOrig); typeUnifyTask.addChildTask(forkOrig);
// schedule compute() on another thread // schedule compute() on another thread
CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f);
CompletableFuture<ComputationResults> resultValues = forkOrigFuture.thenApply( resultValues = resultValues.thenCombine(forkOrigFuture,
(currentThreadResult) -> { (prevResults, currentThreadResult) -> {
forkOrig.context.logger().debug("final Orig 1"); forkOrig.context.logger().debug("final Orig 1");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
return new ComputationResults(currentThreadResult); return new Tuple<>(currentThreadResult, prevResults.getSecond());
}); });
//forks.add(forkOrig); //forks.add(forkOrig);
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return CompletableFuture.completedFuture(new ComputationResults()); throw new UnifyCancelException();
} }
/* FORK ENDE */ /* FORK ENDE */
@@ -109,12 +114,12 @@ public class ContravarianceCase extends VarianceCase {
CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f);
resultValues = resultValues.thenCombine(forkFuture, resultValues = resultValues.thenCombine(forkFuture,
(prevResults, fork_res) -> { (prevResults, fork_res) -> {
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return new ComputationResults(); throw new UnifyCancelException();
} }
context.logger().debug("fork_res: " + fork_res.toString()); context.logger().debug("fork_res: " + fork_res.toString());
context.logger().debug(Boolean.valueOf((typeUnifyTask.isUndefinedPairSetSet(fork_res))).toString()); context.logger().debug(Boolean.valueOf((typeUnifyTask.isUndefinedPairSetSet(fork_res))).toString());
prevResults.addForkResult(fork_res); prevResults.getSecond().add(fork_res);
if (!typeUnifyTask.isUndefinedPairSetSet(fork_res)) { if (!typeUnifyTask.isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement()); aParDef.add(fork.getNextSetElement());
} }
@@ -124,8 +129,8 @@ public class ContravarianceCase extends VarianceCase {
} }
); );
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return CompletableFuture.completedFuture(new ComputationResults()); throw new UnifyCancelException();
} }
} }

View File

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify.cartesianproduct; package de.dhbwstuttgart.typeinference.unify.cartesianproduct;
import de.dhbwstuttgart.exceptions.UnifyCancelException;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task; import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
@@ -14,12 +15,11 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class InvarianceOrConstraintCase extends VarianceCase { public class Variance2Case extends VarianceCase {
// either for invariance or for oderConstraints
protected final int variance = 2; protected final int variance = 2;
protected InvarianceOrConstraintCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) { protected Variance2Case(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
super(isOderConstraint, typeUnifyTask, context); super(isOderConstraint, typeUnifyTask, context);
} }
@@ -37,7 +37,7 @@ public class InvarianceOrConstraintCase extends VarianceCase {
@Override @Override
public CompletableFuture<ComputationResults> computeParallel( public CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> computeParallel(
Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> elems,
Set<UnifyPair> eq, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
@@ -49,6 +49,8 @@ public class InvarianceOrConstraintCase extends VarianceCase {
Set<Set<UnifyPair>> result, Set<Set<UnifyPair>> result,
Set<Set<UnifyPair>> aParDef Set<Set<UnifyPair>> aParDef
) { ) {
CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> resultValuesFuture;
context.logger().debug("var2einstieg"); context.logger().debug("var2einstieg");
Set<TypeUnify2Task> forks = new HashSet<>(); Set<TypeUnify2Task> forks = new HashSet<>();
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
@@ -60,14 +62,13 @@ public class InvarianceOrConstraintCase extends VarianceCase {
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraint)); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraint));
typeUnifyTask.addChildTask(forkOrig); typeUnifyTask.addChildTask(forkOrig);
CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f);
CompletableFuture<ComputationResults> resultValues = forkOrigFuture.thenApply((currentThreadResult) -> { resultValuesFuture = forkOrigFuture.thenApply((currentThreadResult) -> {
forkOrig.context.logger().debug("final Orig 2"); forkOrig.context.logger().debug("final Orig 2");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
return new ComputationResults(currentThreadResult); return new Tuple<>(currentThreadResult, new HashSet<>());
}); });
if (typeUnifyTask.myIsCancelled()) {
if (typeUnifyTask.isExecutionCancelled()) { throw new UnifyCancelException();
return resultValues;
} }
/* FORK ENDE */ /* FORK ENDE */
@@ -91,22 +92,26 @@ public class InvarianceOrConstraintCase extends VarianceCase {
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraintForParallel)); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, context, rekTiefe, new HashSet<>(methodSignatureConstraintForParallel));
typeUnifyTask.addChildTask(fork); typeUnifyTask.addChildTask(fork);
CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f);
resultValues = resultValues.thenCombine(forkFuture, (prevResults, fork_res) -> { resultValuesFuture = resultValuesFuture.thenCombine(forkFuture, (resultValues, fork_res) -> {
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return prevResults; throw new UnifyCancelException();
} }
prevResults.addForkResult(fork_res); resultValues.getSecond().add(fork_res);
fork.context.logger().debug("final 2"); fork.context.logger().debug("final 2");
fork.closeLogFile(); fork.closeLogFile();
return prevResults; return resultValues;
}); });
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return resultValues; throw new UnifyCancelException();
} }
} }
return resultValues; if (typeUnifyTask.myIsCancelled()) {
throw new UnifyCancelException();
}
return resultValuesFuture;
} }
@Override @Override

View File

@@ -5,9 +5,9 @@ import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.Logger;
import de.dhbwstuttgart.util.Tuple; import de.dhbwstuttgart.util.Tuple;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -17,10 +17,10 @@ public abstract class VarianceCase {
public static VarianceCase createFromVariance(int variance, boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) { public static VarianceCase createFromVariance(int variance, boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
return switch (variance) { return switch (variance) {
case 0 -> new UnknownVarianceCase(isOderConstraint, typeUnifyTask, context); case 0 -> new Variance0Case(isOderConstraint, typeUnifyTask, context);
case 1 -> new ContravarianceCase(isOderConstraint, typeUnifyTask, context); case 1 -> new Variance1Case(isOderConstraint, typeUnifyTask, context);
case -1 -> new CovarianceCase(isOderConstraint, typeUnifyTask, context); case -1 -> new VarianceM1Case(isOderConstraint, typeUnifyTask, context);
case 2 -> new InvarianceOrConstraintCase(isOderConstraint, typeUnifyTask, context); case 2 -> new Variance2Case(isOderConstraint, typeUnifyTask, context);
default -> throw new RuntimeException("Invalid variance: " + variance); default -> throw new RuntimeException("Invalid variance: " + variance);
}; };
} }
@@ -72,7 +72,7 @@ public abstract class VarianceCase {
/** /**
* *
*/ */
public abstract CompletableFuture<ComputationResults> computeParallel( public abstract CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> computeParallel(
Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> elems,
Set<UnifyPair> eq, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
@@ -104,29 +104,4 @@ public abstract class VarianceCase {
Set<Set<UnifyPair>> aParDef, Set<Set<UnifyPair>> aParDef,
List<Set<UnifyPair>> nextSetAsList List<Set<UnifyPair>> nextSetAsList
); );
/**
* Wrapper class for the parallel computation results
*/
public static class ComputationResults {
public Set<Set<UnifyPair>> mainResult;
public Set<Set<Set<UnifyPair>>> forkResults;
public ComputationResults() {
this(new HashSet<>(), new HashSet<>());
}
public ComputationResults(Set<Set<UnifyPair>> mainResult) {
this(mainResult, new HashSet<>());
}
public ComputationResults(Set<Set<UnifyPair>> mainResult, Set<Set<Set<UnifyPair>>> forkResults) {
this.mainResult = mainResult;
this.forkResults = forkResults;
}
void addForkResult(Set<Set<UnifyPair>> forkResult) {
forkResults.add(forkResult);
}
}
} }

View File

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify.cartesianproduct; package de.dhbwstuttgart.typeinference.unify.cartesianproduct;
import de.dhbwstuttgart.exceptions.UnifyCancelException;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task; import de.dhbwstuttgart.typeinference.unify.TypeUnify2Task;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
@@ -16,11 +17,11 @@ import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class CovarianceCase extends VarianceCase { public class VarianceM1Case extends VarianceCase {
protected final int variance = -1; protected final int variance = -1;
protected CovarianceCase(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) { protected VarianceM1Case(boolean isOderConstraint, TypeUnifyTask typeUnifyTask, UnifyContext context) {
super(isOderConstraint, typeUnifyTask, context); super(isOderConstraint, typeUnifyTask, context);
} }
@@ -48,7 +49,7 @@ public class CovarianceCase extends VarianceCase {
@Override @Override
public CompletableFuture<ComputationResults> computeParallel( public CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> computeParallel(
Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> elems,
Set<UnifyPair> eq, Set<UnifyPair> eq,
List<Set<Constraint<UnifyPair>>> oderConstraints, List<Set<Constraint<UnifyPair>>> oderConstraints,
@@ -60,6 +61,10 @@ public class CovarianceCase extends VarianceCase {
Set<Set<UnifyPair>> result, Set<Set<UnifyPair>> result,
Set<Set<UnifyPair>> aParDef Set<Set<UnifyPair>> aParDef
) { ) {
CompletableFuture<Tuple<Set<Set<UnifyPair>>, Set<Set<Set<UnifyPair>>>>> resultValues = CompletableFuture.completedFuture(new Tuple<>(
new HashSet<>(), new HashSet<>()
));
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems); Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Constraint<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
@@ -70,16 +75,16 @@ public class CovarianceCase extends VarianceCase {
typeUnifyTask.addChildTask(forkOrig); typeUnifyTask.addChildTask(forkOrig);
// schedule compute() on another thread // schedule compute() on another thread
CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkOrigFuture = CompletableFuture.supplyAsync(forkOrig::compute, context.executor()).thenCompose(f -> f);
CompletableFuture<ComputationResults> resultValues = forkOrigFuture.thenApply( resultValues = resultValues.thenCombine(forkOrigFuture,
(currentThreadResult) -> { (prevResults, currentThreadResult) -> {
forkOrig.context.logger().debug("final Orig -1"); forkOrig.context.logger().debug("final Orig -1");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
return new ComputationResults(currentThreadResult); return new Tuple<>(currentThreadResult, prevResults.getSecond());
}); });
//forks.add(forkOrig); //forks.add(forkOrig);
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return resultValues; throw new UnifyCancelException();
} }
/* FORK ENDE */ /* FORK ENDE */
@@ -110,12 +115,12 @@ public class CovarianceCase extends VarianceCase {
CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f); CompletableFuture<Set<Set<UnifyPair>>> forkFuture = CompletableFuture.supplyAsync(fork::compute, context.executor()).thenCompose(f -> f);
resultValues = resultValues.thenCombine(forkFuture, resultValues = resultValues.thenCombine(forkFuture,
(prevResults, fork_res) -> { (prevResults, fork_res) -> {
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return prevResults; throw new UnifyCancelException();
} }
context.logger().debug(() -> "fork_res: " + fork_res.toString()); context.logger().debug(() -> "fork_res: " + fork_res.toString());
context.logger().debug(() -> Boolean.valueOf((typeUnifyTask.isUndefinedPairSetSet(fork_res))).toString()); context.logger().debug(() -> Boolean.valueOf((typeUnifyTask.isUndefinedPairSetSet(fork_res))).toString());
prevResults.addForkResult(fork_res); prevResults.getSecond().add(fork_res);
if (!typeUnifyTask.isUndefinedPairSetSet(fork_res)) { if (!typeUnifyTask.isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement()); aParDef.add(fork.getNextSetElement());
} }
@@ -125,8 +130,8 @@ public class CovarianceCase extends VarianceCase {
} }
); );
if (typeUnifyTask.isExecutionCancelled()) { if (typeUnifyTask.myIsCancelled()) {
return resultValues; throw new UnifyCancelException();
} }
} }

View File

@@ -5,7 +5,6 @@ import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap; import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry; import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTaskHelper;
import de.dhbwstuttgart.typeinference.unify.UnifyContext; import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.util.Logger; import de.dhbwstuttgart.util.Logger;
import java.io.IOException; import java.io.IOException;
@@ -127,7 +126,7 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
} }
// Build the alternative representation with strings as keys // Build the alternative representation with strings as keys
strInheritanceGraph = TypeUnifyTaskHelper.getPresizedHashMap(inheritanceGraph.size()); strInheritanceGraph = new HashMap<>();
for(UnifyType key : inheritanceGraph.keySet()) { for(UnifyType key : inheritanceGraph.keySet()) {
if(!strInheritanceGraph.containsKey(key.getName())) if(!strInheritanceGraph.containsKey(key.getName()))
strInheritanceGraph.put(key.getName(), new HashSet<>()); strInheritanceGraph.put(key.getName(), new HashSet<>());
@@ -240,8 +239,8 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
} }
} }
HashSet<UnifyType> resut = result.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new)); HashSet<UnifyType> resut = result.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new));
if(resut.equals(types.stream().map(Pair::getKey).collect(Collectors.toCollection(HashSet::new)))) if(resut.equals(types.stream().map(x -> x.getKey()).collect(Collectors.toCollection(HashSet::new))))
return resut; return resut;
return computeSmaller(result); return computeSmaller(result);
} }
@@ -273,8 +272,8 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
@Override @Override
//Eingefuegt PL 2018-05-24 F-Bounded Problematik //Eingefuegt PL 2018-05-24 F-Bounded Problematik
public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded, SourceLoc location) { public Set<UnifyType> greater(UnifyType type, Set<UnifyType> fBounded, SourceLoc location) {
Set<UnifyType> ret = greaterHash.get(new hashKeyType(type)); Set<UnifyType> ret;
if (ret != null) { if ((ret = greaterHash.get(new hashKeyType(type))) != null) {
//context.logger().info(greaterHash); //context.logger().info(greaterHash);
return new HashSet<>(ret); return new HashSet<>(ret);
} }
@@ -514,35 +513,28 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
@Override @Override
public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded) { public Set<UnifyType> grArg(FunNType type, Set<UnifyType> fBounded) {
Set<UnifyType> smaller = smaller(type, fBounded); Set<UnifyType> result = new HashSet<UnifyType>();
Set<UnifyType> greater = greater(type, fBounded);
Set<UnifyType> result = new HashSet<UnifyType>((int)((1 + smaller.size() + greater.size()) * 1.5));
result.add(type); result.add(type);
smaller.forEach(x -> result.add(new SuperType(x))); smaller(type, fBounded).forEach(x -> result.add(new SuperType(x)));
greater.forEach(x -> result.add(new ExtendsType(x))); greater(type, fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded) { public Set<UnifyType> grArg(ExtendsType type, Set<UnifyType> fBounded) {
UnifyType t = type.getExtendedType(); Set<UnifyType> result = new HashSet<UnifyType>();
Set<UnifyType> greater = greater(t, fBounded);
Set<UnifyType> result = new HashSet<UnifyType>((int)((1 + greater.size()) * 1.5));
result.add(type); result.add(type);
greater.forEach(x -> result.add(new ExtendsType(x))); UnifyType t = type.getExtendedType();
greater(t, fBounded).forEach(x -> result.add(new ExtendsType(x)));
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded) { public Set<UnifyType> grArg(SuperType type, Set<UnifyType> fBounded) {
UnifyType t = type.getSuperedType(); Set<UnifyType> result = new HashSet<UnifyType>();
Set<UnifyType> smaller = smaller(t, fBounded);
Set<UnifyType> result = TypeUnifyTaskHelper.getPresizedHashSet(1 + smaller.size());
result.add(type); result.add(type);
smaller.forEach(x -> result.add(new SuperType(x))); UnifyType t = type.getSuperedType();
smaller(t, fBounded).forEach(x -> result.add(new SuperType(x)));
return result; return result;
} }
@@ -574,13 +566,11 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
@Override @Override
public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded) { public Set<UnifyType> smArg(ExtendsType type, Set<UnifyType> fBounded) {
UnifyType t = type.getExtendedType(); Set<UnifyType> result = new HashSet<UnifyType>();
Set<UnifyType> smaller = smaller(t, fBounded);
Set<UnifyType> result = TypeUnifyTaskHelper.getPresizedHashSet(2 * (1 + smaller.size()));
result.add(type); result.add(type);
UnifyType t = type.getExtendedType();
result.add(t); result.add(t);
smaller.forEach(x -> { smaller(t, fBounded).forEach(x -> {
result.add(new ExtendsType(x)); result.add(new ExtendsType(x));
result.add(x); result.add(x);
}); });
@@ -590,14 +580,12 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
@Override @Override
public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded) { public Set<UnifyType> smArg(SuperType type, Set<UnifyType> fBounded) {
UnifyType t = type.getSuperedType(); Set<UnifyType> result = new HashSet<UnifyType>();
Set<UnifyType> greater = greater(t, fBounded);
Set<UnifyType> result = TypeUnifyTaskHelper.getPresizedHashSet(2 * (1 + greater.size()));
result.add(type); result.add(type);
UnifyType t = type.getSuperedType();
result.add(t); result.add(t);
//*** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen //*** ACHTUNG das koennte FALSCH sein PL 2018-05-23 evtl. HashSet durch smArg durchschleifen
greater.forEach(x -> { greater(t, fBounded).forEach(x -> {
result.add(new SuperType(x)); result.add(new SuperType(x));
result.add(x); result.add(x);
}); });
@@ -615,7 +603,7 @@ public class FiniteClosure implements IFiniteClosure, ISerializableData {
public Set<UnifyType> getAllTypesByName(String typeName) { public Set<UnifyType> getAllTypesByName(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if(!strInheritanceGraph.containsKey(typeName))
return new HashSet<>(); return new HashSet<>();
return strInheritanceGraph.get(typeName).stream().map(Node::getContent).collect(Collectors.toCollection(HashSet::new)); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
} }
@Override @Override

View File

@@ -171,65 +171,29 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
left.add(p4); left.add(p4);
*/ */
Set<UnifyPair> lefteq = new HashSet<>();
Set<UnifyPair> leftle = new HashSet<>();
Set<UnifyPair> leftlewc = new HashSet<>();
Set<UnifyPair> lefteqOder = new HashSet<>();
Set<UnifyPair> lefteqRet = new HashSet<>();
Set<UnifyPair> leftleOder = new HashSet<>();
for (var x : left) {
boolean isLeftPlaceholder = x.getLhsType() instanceof PlaceholderType;
boolean isRightPlaceholder = x.getRhsType() instanceof PlaceholderType;
boolean hasPlaceholder = isLeftPlaceholder || isRightPlaceholder;
if (isLeftPlaceholder && x.getPairOp() == PairOperator.EQUALSDOT) lefteq.add(x);
if (hasPlaceholder && x.getPairOp() == PairOperator.SMALLERDOT) leftle.add(x);
if (hasPlaceholder && x.getPairOp() == PairOperator.SMALLERDOTWC) leftlewc.add(x);
UnifyPair y = x.getGroundBasePair();
boolean isBasePairLeftPlaceholder = y.getLhsType() instanceof PlaceholderType;
boolean isBasePairRightPlaceholder = y.getRhsType() instanceof PlaceholderType;
if (isBasePairLeftPlaceholder && !isBasePairRightPlaceholder && x.getPairOp() == PairOperator.EQUALSDOT) {
lefteqOder.add(x);
}
else if (isBasePairRightPlaceholder && ((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1) {
lefteqRet.add(x);
}
else if (x.getPairOp() == PairOperator.SMALLERDOT) {
leftleOder.add(x);
}
}
Set<UnifyPair> righteq = new HashSet<>();
Set<UnifyPair> rightle = new HashSet<>();
Set<UnifyPair> rightlewc = new HashSet<>();
Set<UnifyPair> righteqOder = new HashSet<>();
Set<UnifyPair> righteqRet = new HashSet<>();
Set<UnifyPair> rightleOder = new HashSet<>();
for (var x : right) {
boolean isLeftPlaceholder = x.getLhsType() instanceof PlaceholderType;
boolean isRightPlaceholder = x.getRhsType() instanceof PlaceholderType;
boolean hasPlaceholder = isLeftPlaceholder || isRightPlaceholder;
if (isLeftPlaceholder && x.getPairOp() == PairOperator.EQUALSDOT) righteq.add(x);
if (hasPlaceholder && x.getPairOp() == PairOperator.SMALLERDOT) rightle.add(x);
if (hasPlaceholder && x.getPairOp() == PairOperator.SMALLERDOTWC) rightlewc.add(x);
UnifyPair y = x.getGroundBasePair();
boolean isBasePairLeftPlaceholder = y.getLhsType() instanceof PlaceholderType;
boolean isBasePairRightPlaceholder = y.getRhsType() instanceof PlaceholderType;
if (isBasePairLeftPlaceholder && !isBasePairRightPlaceholder && x.getPairOp() == PairOperator.EQUALSDOT) {
righteqOder.add(x);
}
else if (isBasePairRightPlaceholder && ((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1) {
righteqRet.add(x);
}
else if (x.getPairOp() == PairOperator.SMALLERDOT) {
rightleOder.add(x);
}
}
Set<UnifyPair> lefteq = left.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> righteq = right.stream()
.filter(x -> (x.getLhsType() instanceof PlaceholderType && x.getPairOp() == PairOperator.EQUALSDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftle = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightle = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> leftlewc = left.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightlewc = right.stream()
.filter(x -> ((x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)
&& x.getPairOp() == PairOperator.SMALLERDOTWC))
.collect(Collectors.toCollection(HashSet::new));
//context.logger().info(left.toString()); //context.logger().info(left.toString());
//Fall 2 //Fall 2
//if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) { //if (lefteq.iterator().next().getLhsType().getName().equals("AJO")) {
@@ -237,13 +201,53 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
//} //}
//ODER-CONSTRAINT //ODER-CONSTRAINT
// Set<UnifyPair> leftBase = left.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new)); Set<UnifyPair> leftBase = left.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
// Set<UnifyPair> rightBase = right.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new)); Set<UnifyPair> rightBase = right.stream().map(x -> x.getGroundBasePair()).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> lefteqOder = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
/*try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
((FiniteClosure)fc).logFile.write("right: " + right.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y: " + y.toString() +"\n");
((FiniteClosure)fc).logFile.write("y.getLhsType() : " + y.getLhsType() .toString() +"\n\n");
((FiniteClosure)fc).logFile.write("y.getRhsType(): " + y.getRhsType().toString() +"\n");
((FiniteClosure)fc).logFile.write("x.getPairOp(): " + x.getPairOp().toString() +"\n\n");
}
catch (IOException ie) {
} */
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqOder); left.removeAll(lefteqOder);
left.removeAll(lefteqRet); Set<UnifyPair> righteqOder = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getLhsType() instanceof PlaceholderType &&
!(y.getRhsType() instanceof PlaceholderType) &&
x.getPairOp() == PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqOder); right.removeAll(righteqOder);
Set<UnifyPair> lefteqRet = left.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
left.removeAll(lefteqRet);
Set<UnifyPair> righteqRet = right.stream()
.filter(x -> { UnifyPair y = x.getGroundBasePair();
return (y.getRhsType() instanceof PlaceholderType &&
((PlaceholderType)y.getRhsType()).getOrCons() == (byte)-1);})
.collect(Collectors.toCollection(HashSet::new));
right.removeAll(righteqRet); right.removeAll(righteqRet);
Set<UnifyPair> leftleOder = left.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> rightleOder = right.stream()
.filter(x -> (x.getPairOp() == PairOperator.SMALLERDOT))
.collect(Collectors.toCollection(HashSet::new));
/* /*
synchronized(this) { synchronized(this) {
@@ -269,31 +273,43 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
int compareEq; int compareEq;
if (lefteqOder.size() == 1 && righteqOder.size() == 1 && lefteqRet.size() == 1 && righteqRet.size() == 1) { if (lefteqOder.size() == 1 && righteqOder.size() == 1 && lefteqRet.size() == 1 && righteqRet.size() == 1) {
Match m = new Match(); Match m = new Match();
compareEq = compareEq(lefteqOder.iterator().next().getGroundBasePair(), righteqOder.iterator().next().getGroundBasePair()); if ((compareEq = compareEq(lefteqOder.iterator().next().getGroundBasePair(), righteqOder.iterator().next().getGroundBasePair())) == -1) {
if (compareEq == -1) {
ArrayList<UnifyPair> matchList = ArrayList<UnifyPair> matchList =
rightleOder.stream().map(x -> { rightleOder.stream().map(x -> {
UnifyPair leftElem = leftleOder.stream() UnifyPair leftElem = leftleOder.stream()
.filter(y -> y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType())) .filter(y -> y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
.findAny().orElseThrow(); .findAny().get();
return new UnifyPair(x.getRhsType(), leftElem.getRhsType(), PairOperator.EQUALSDOT);} return new UnifyPair(x.getRhsType(), leftElem.getRhsType(), PairOperator.EQUALSDOT);})
)
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
if (m.match(matchList).isPresent()) {
return (m.match(matchList).isPresent()) ? -1 : 0; //try { ((FiniteClosure)fc).logFile.write("result1: -1 \n\n"); } catch (IOException ie) {}
return -1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result1: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else if (compareEq == 1) { } else if (compareEq == 1) {
ArrayList<UnifyPair> matchList = ArrayList<UnifyPair> matchList =
leftleOder.stream().map(x -> { leftleOder.stream().map(x -> {
UnifyPair rightElem = rightleOder.stream() UnifyPair rightElem = rightleOder.stream()
.filter(y -> y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType())) .filter(y ->
.findAny().orElseThrow(); y.getGroundBasePair().getLhsType().equals(x.getGroundBasePair().getLhsType()))
return new UnifyPair(x.getRhsType(), rightElem.getRhsType(), PairOperator.EQUALSDOT);} .findAny().get();
) return new UnifyPair(x.getRhsType(), rightElem.getRhsType(), PairOperator.EQUALSDOT);})
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
return (m.match(matchList).isPresent()) ? 1 : 0; if (m.match(matchList).isPresent()) {
//try { ((FiniteClosure)fc).logFile.write("result2: 1 \n\n"); } catch (IOException ie) {}
return 1;
}
else {
//try { ((FiniteClosure)fc).logFile.write("result2: 0 \n\n"); } catch (IOException ie) {}
return 0;
}
} else { } else {
/* /*
synchronized(this) {
try {
((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n"); ((FiniteClosure)fc).logFile.write("leftBase: " + leftBase.toString() +"\n");
((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n"); ((FiniteClosure)fc).logFile.write("rightBase: " + rightBase.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n"); ((FiniteClosure)fc).logFile.write("left: " + left.toString() +"\n");
@@ -306,6 +322,10 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n"); ((FiniteClosure)fc).logFile.write("rightleOder: " + rightleOder.toString() +"\n\n");
((FiniteClosure)fc).logFile.write("result3: 0 \n\n"); ((FiniteClosure)fc).logFile.write("result3: 0 \n\n");
((FiniteClosure)fc).logFile.flush(); ((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
}
*/ */
return 0; return 0;
} }
@@ -372,12 +392,12 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
//TODO: Hier wird bei Wildcards nicht das richtige compare aufgerufen PL 18-04-20 //TODO: Hier wird bei Wildcards nicht das richtige compare aufgerufen PL 18-04-20
Pair<Integer, Set<UnifyPair>> int_Unifier = compare(lseq.getRhsType(), rseq.getRhsType()); Pair<Integer, Set<UnifyPair>> int_Unifier = compare(lseq.getRhsType(), rseq.getRhsType());
Unifier uni = new Unifier(); Unifier uni = new Unifier();
int_Unifier.getValue().orElseThrow().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType())); int_Unifier.getValue().get().forEach(x -> uni.add((PlaceholderType) x.getLhsType(), x.getRhsType()));
if (!lseq.getRhsType().getName().equals(rseq.getRhsType().getName()) if (!lseq.getRhsType().getName().equals(rseq.getRhsType().getName())
|| leftlewc.isEmpty() || rightlewc.isEmpty()) return int_Unifier.getKey(); || leftlewc.isEmpty() || rightlewc.isEmpty()) return int_Unifier.getKey();
else { else {
Set <UnifyPair> lsleuni = leftlewc.stream().map(uni::apply).collect(Collectors.toCollection(HashSet::new)); Set <UnifyPair> lsleuni = leftlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
Set <UnifyPair> rsleuni = rightlewc.stream().map(uni::apply).collect(Collectors.toCollection(HashSet::new)); Set <UnifyPair> rsleuni = rightlewc.stream().map(x -> uni.apply(x)).collect(Collectors.toCollection(HashSet::new));
BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;}; BinaryOperator<HashMap<UnifyType,UnifyPair>> combiner = (x,y) -> { x.putAll(y); return x;};
HashMap<UnifyType,UnifyPair> hm; HashMap<UnifyType,UnifyPair> hm;
@@ -398,7 +418,6 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
} }
} else { } else {
if (!leftlewc.isEmpty()) { if (!leftlewc.isEmpty()) {
/*
Set<UnifyPair> subst; Set<UnifyPair> subst;
subst = leftlewc.stream().map(x -> { subst = leftlewc.stream().map(x -> {
if (x.getLhsType() instanceof PlaceholderType) { if (x.getLhsType() instanceof PlaceholderType) {
@@ -407,7 +426,6 @@ public class OrderingUnifyPair extends OrderingExtend<Set<UnifyPair>> {
else { else {
return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT); return new UnifyPair(x.getRhsType(), x.getLhsType(), PairOperator.EQUALSDOT);
}}).collect(Collectors.toCollection(HashSet::new)); }}).collect(Collectors.toCollection(HashSet::new));
*/
Unifier uni = new Unifier(); Unifier uni = new Unifier();
lseq = uni.apply(lseq); lseq = uni.apply(lseq);
} }

View File

@@ -2,14 +2,11 @@ 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 java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -19,12 +16,11 @@ 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");
protected final Writer writer; protected final Writer writer;
protected final String prefix; protected final String prefix;
public static Logger NULL_LOGGER = new NullLogger();
public Logger() { public Logger() {
this(null, ""); this(null, "");
} }
@@ -58,7 +54,7 @@ public class Logger {
/** /**
* Create a new logger object that inherits the writer of the given logger object * Create a new logger object that inherits the writer of the given logger object
* *
* @param logger The old logger object that will provide the writer * @param logger The old logger object, that will provide the writer
* @return The new prefix for the new logger object * @return The new prefix for the new logger object
*/ */
public static Logger inherit(Logger logger, String newPrefix) { public static Logger inherit(Logger logger, String newPrefix) {
@@ -77,7 +73,6 @@ public class Logger {
case INFO -> colorize(fullPrefix, Attribute.BLUE_TEXT()); case INFO -> colorize(fullPrefix, Attribute.BLUE_TEXT());
case WARNING -> colorize(fullPrefix, Attribute.YELLOW_TEXT()); case WARNING -> colorize(fullPrefix, Attribute.YELLOW_TEXT());
case ERROR -> colorize(fullPrefix, Attribute.RED_TEXT()); case ERROR -> colorize(fullPrefix, Attribute.RED_TEXT());
case SUCCESS -> colorize(fullPrefix, Attribute.GREEN_TEXT());
}; };
} }
@@ -88,15 +83,7 @@ public class Logger {
*/ */
protected void print(String s, LogLevel logLevel) { protected void print(String s, LogLevel logLevel) {
String coloredPrefix = this.getPrefix(logLevel); String coloredPrefix = this.getPrefix(logLevel);
if (logLevel.value > LogLevel.WARNING.value) {
// if we are running the server, prepend the timestamp
if(SocketServer.isServerRunning()) {
String timestamp = LocalDateTime.now().format(timeFormatter);
coloredPrefix = "[" + timestamp + "] " + coloredPrefix;
}
// output to the correct output-stream
if (logLevel.getValue() == LogLevel.ERROR.getValue()) {
System.out.println(coloredPrefix + s); System.out.println(coloredPrefix + s);
} }
else { else {
@@ -105,11 +92,11 @@ public class Logger {
} }
public boolean isLogLevelActive(LogLevel logLevel) { public boolean isLogLevelActive(LogLevel logLevel) {
return logLevel.isHigherOrEqualTo(ConsoleInterface.logLevel); return logLevel.value >= ConsoleInterface.logLevel.value;
} }
/** /**
* Write text to the attached writer if there is any * Write text to the attached writer, if there is any
* @param s The string to print * @param s The string to print
*/ */
protected void write(String s) { protected void write(String s) {
@@ -126,20 +113,6 @@ public class Logger {
} }
} }
public String findLogCaller() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
final String thisFileName = stackTrace[0].getFileName();
int i = 0;
StackTraceElement currentElement = stackTrace[i];
while (++i < stackTrace.length) {
currentElement = stackTrace[i];
if (!Objects.equals(thisFileName, currentElement.getFileName())) {
break;
}
}
return ".(" + currentElement.getFileName() + ":" + currentElement.getLineNumber() + ")";
}
/** /**
* Base method for logging a string value. Should mostly be used by the Logger internal functions that * Base method for logging a string value. Should mostly be used by the Logger internal functions that
* abstract the logLevel away from the parameters * abstract the logLevel away from the parameters
@@ -150,8 +123,6 @@ public class Logger {
*/ */
public void log(String s, LogLevel logLevel) { public void log(String s, LogLevel logLevel) {
if (isLogLevelActive(logLevel)) { if (isLogLevelActive(logLevel)) {
// prepend the call to the logger instance
// s = findLogCaller() + "\n" + s;
this.print(s, logLevel); this.print(s, logLevel);
this.write(s); this.write(s);
} }
@@ -169,7 +140,7 @@ public class Logger {
/** /**
* Output a debug message * Replaces the old FileWriter.write() call
* @param s The string to log * @param s The string to log
*/ */
public void debug(String s) { public void debug(String s) {
@@ -183,7 +154,7 @@ public class Logger {
} }
/** /**
* Output an info message * Replaces the old System.out.println() call
* @param s The string to log * @param s The string to log
*/ */
public void info(String s) { public void info(String s) {
@@ -224,21 +195,6 @@ public class Logger {
this.log(supp, LogLevel.ERROR); this.log(supp, LogLevel.ERROR);
} }
/**
* Output a success message
* @param s The string to log
*/
public void success(String s) {
this.log(s, LogLevel.SUCCESS);
}
public void success(Object o) {
this.log(o, LogLevel.SUCCESS);
}
public void success(Supplier<String> supp) {
this.log(supp, LogLevel.SUCCESS);
}
/** /**
* Special logging function that prints a throwable object and all of its recursive causes (including stacktrace) * Special logging function that prints a throwable object and all of its recursive causes (including stacktrace)
* as an error * as an error
@@ -252,7 +208,7 @@ public class Logger {
" | " + stackTraceElement.toString() " | " + stackTraceElement.toString()
).collect(Collectors.joining("\n")); ).collect(Collectors.joining("\n"));
// if there is a cause printed afterward, announce it with the print of the exception // if there will be a cause printed afterward, announce it with the print of the exception
if (throwable.getCause() != null) { if (throwable.getCause() != null) {
s += "\n\nCaused by: "; s += "\n\nCaused by: ";
} }
@@ -279,50 +235,22 @@ public class Logger {
/** /**
* An enum representing the different log levels as integers: * An enum representing the different log levels as integers
* <ul>
* <li>DEBUG: highly specific output only for debugging</li>
* <li>INFO: informational output about the current state of the program</li>
* <li>WARNING: warnings about potential issues or an unexpected state</li>
* <li>ERROR: invalid states, errors and exceptions</li>
* <li>SUCCESS: successfully executed key steps of the program</li>
* </ul>
*/ */
public enum LogLevel { public enum LogLevel {
/** Highly specific output only for debugging */ // all the output
DEBUG(0), DEBUG(0),
/** Informational output about the current state of the program */ // a lot of info about the process
INFO(1), INFO(1),
/** Warnings about potential issues or an unexpected state **/ // warnings and up
WARNING(2), WARNING(2),
/** Invalid states, errors and exceptions */ // only errors and exceptions
ERROR(3), ERROR(3);
/** Successfully executed key steps of the program */
SUCCESS(4);
private final int value; private final int value;
LogLevel(final int newValue) { LogLevel(final int newValue) {
value = newValue; value = newValue;
} }
public boolean isHigherOrEqualTo(LogLevel other) {
return this.value >= other.value;
}
public int getValue() {
return value;
}
public static LogLevel fromValue(int value) {
return switch (value) {
case 0 -> LogLevel.DEBUG;
case 1 -> LogLevel.INFO;
case 2 -> LogLevel.WARNING;
case 3 -> LogLevel.ERROR;
case 4 -> LogLevel.SUCCESS;
default -> throw new RuntimeException("Invalid log level value: " + value);
};
}
} }
@@ -332,7 +260,7 @@ public class Logger {
private static class NullLogger extends Logger { private static class NullLogger extends Logger {
@Override @Override
public void log(String s, LogLevel logLevel) { public void log(String s, LogLevel logLevel) {
// Do nothing. Yay // do nothing. Yay
} }
} }
} }

View File

@@ -1,12 +1,9 @@
package server; package server;
import de.dhbwstuttgart.core.ConsoleInterface;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.core.JavaTXServer; import de.dhbwstuttgart.core.JavaTXServer;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.server.SocketClient; import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.packet.SetAutoclosePacket;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
@@ -30,7 +27,6 @@ import java.io.Writer;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@@ -43,10 +39,6 @@ import static org.junit.Assert.*;
@Ignore("Server tests create huge overhead, so they are ignored until required") @Ignore("Server tests create huge overhead, so they are ignored until required")
public class ServerTest { public class ServerTest {
public ServerTest() {
ConsoleInterface.unifyServerUrl = Optional.of("ws://localhost:5000");
}
@Test @Test
public void checkServer_Scalar() throws IOException, ClassNotFoundException { public void checkServer_Scalar() throws IOException, ClassNotFoundException {
compareLocalAndServerResult("Scalar.jav"); compareLocalAndServerResult("Scalar.jav");
@@ -60,11 +52,11 @@ public class ServerTest {
protected void compareLocalAndServerResult(final String filename) throws IOException, ClassNotFoundException { protected void compareLocalAndServerResult(final String filename) throws IOException, ClassNotFoundException {
File file = Path.of(TestCodegen.path.toString(), filename).toFile(); File file = Path.of(TestCodegen.path.toString(), filename).toFile();
// get information from the compiler // get information from compiler
JavaTXCompiler compiler = new JavaTXCompiler(List.of(file)); JavaTXCompiler compiler = new JavaTXCompiler(List.of(file));
// NOW: simulate the call to method typeInference. Once via server and once locally // NOW: simulate the call to method typeInference. Once via server and once locally
// if everything works, they should neither interfere with each other nor differ in their result // if everything works, they should neither interfere with each other, nor differ in their result
// get the values from the compiler // get the values from the compiler
PlaceholderRegistry placeholderRegistry = JavaTXCompiler.defaultClientPlaceholderRegistry; //new PlaceholderRegistry(); PlaceholderRegistry placeholderRegistry = JavaTXCompiler.defaultClientPlaceholderRegistry; //new PlaceholderRegistry();
@@ -94,10 +86,8 @@ public class ServerTest {
PlaceholderRegistry prCopy = JavaTXCompiler.defaultClientPlaceholderRegistry.deepClone(); PlaceholderRegistry prCopy = JavaTXCompiler.defaultClientPlaceholderRegistry.deepClone();
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure); UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyContext context = new UnifyContext(Logger.NULL_LOGGER, true, urm, usedTasks, prCopy); UnifyContext context = new UnifyContext(Logger.NULL_LOGGER, true, urm, usedTasks, prCopy);
SocketClient.execute(SetAutoclosePacket.create()); SocketClient socketClient = new SocketClient("ws://localhost:5000");
List<ResultSet> serverResult = SocketClient.executeAndGet( List<ResultSet> serverResult = socketClient.execute(finiteClosure, cons, unifyCons, context);
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
).getResultSet(context);
// close the server // close the server
server.forceStop(); server.forceStop();

View File

@@ -1,22 +0,0 @@
import java.util.Vector;
import java.util.List;
class Main {
public static void main(String[] args) {
var grid = new Vector<Vector<Boolean>>(List.of(
new Vector<Boolean>(List.of(false, false, false)),
new Vector<Boolean>(List.of(false, false, false)),
new Vector<Boolean>(List.of(false, true, false))
));
BFS img = new BFS();
Pos pos = img.search(grid);
System.out.println("Found at: x=" + pos.x + " | y=" + pos.y);
}
}