Compare commits

...

285 Commits

Author SHA1 Message Date
dholle 6f62795504 Remove OLFun2 closing #391
SonarQube Scan / SonarQube Trigger (push) Failing after 1m19s
2026-02-19 15:21:44 +01:00
dholle 4f82ba51f0 #390 also writing
SonarQube Scan / SonarQube Trigger (push) Failing after 1m23s
2026-02-19 14:50:04 +01:00
dholle fd34d7f704 Merge branch 'master' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore
SonarQube Scan / SonarQube Trigger (push) Failing after 1m42s
2026-02-18 11:41:39 +01:00
dholle b3495c57ab Fix #390 2026-02-18 11:41:23 +01:00
julian d59d414ae5 fix invalid generic types in lambda signature
SonarQube Scan / SonarQube Trigger (push) Failing after 1m36s
2026-01-29 15:52:05 +01:00
dholle 9117a608c8 Fix up some stuff
SonarQube Scan / SonarQube Trigger (push) Failing after 1m16s
2026-01-15 18:16:49 +01:00
dholle f57a92f632 Undo change that broke things
SonarQube Scan / SonarQube Trigger (push) Failing after 1m27s
2026-01-14 14:59:15 +01:00
dholle 19d5792451 Fix #387
SonarQube Scan / SonarQube Trigger (push) Failing after 1m31s
2026-01-14 11:14:14 +01:00
dholle 4f39f62283 Add better output
SonarQube Scan / SonarQube Trigger (push) Failing after 1m42s
2026-01-09 16:26:27 +01:00
pl@gohorb.ba-horb.de 2be1537cb0 y2 -> ys
SonarQube Scan / SonarQube Trigger (push) Failing after 1m17s
2026-01-09 13:48:57 +01:00
dholle ef6d5683d4 Zip example
SonarQube Scan / SonarQube Trigger (push) Failing after 1m23s
2026-01-09 12:49:25 +01:00
dholle 9f84eb6293 Merge patternMatching
SonarQube Scan / SonarQube Trigger (push) Failing after 2m23s
2026-01-08 19:43:57 +01:00
dholle 3d50924c98 This might be needed
SonarQube Scan / SonarQube Trigger (push) Successful in 2m24s
2025-12-10 17:24:08 +01:00
dholle eb0b4f42c3 NOW fix the tests hopefully
SonarQube Scan / SonarQube Trigger (push) Successful in 2m21s
2025-12-10 17:13:51 +01:00
dholle 6e0c85632f Fix tests, make them use the compiler directly instead of messing with its internals
SonarQube Scan / SonarQube Trigger (push) Failing after 1m16s
2025-12-10 15:47:45 +01:00
dholle 3c606b8f6a Work on #384
SonarQube Scan / SonarQube Trigger (push) Failing after 1m21s
2025-12-10 14:34:42 +01:00
dholle a5b2d14481 This doesn't work but lets go from here
SonarQube Scan / SonarQube Trigger (push) Successful in 2m35s
2025-12-04 16:19:20 +01:00
dholle 6ae5d7ce0b Add --infer-together flag
SonarQube Scan / SonarQube Trigger (push) Successful in 2m22s
2025-12-04 15:34:04 +01:00
dholle ff77630cdf Add JCommander option parser
SonarQube Scan / SonarQube Trigger (push) Successful in 3m9s
2025-12-04 13:27:31 +01:00
dholle 2d9456317e Merge branch 'f.holzwarth-feat/unify-server-mergeMaster'
SonarQube Scan / SonarQube Trigger (push) Successful in 3m52s
2025-12-03 12:27:19 +01:00
dholle 6f18180567 Remove unused imports 2025-12-03 12:13:01 +01:00
dholle ed1be59546 Merge branch 'master' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore
SonarQube Scan / SonarQube Trigger (push) Successful in 2m56s
2025-11-27 15:32:46 +01:00
dholle 42fabc115e Fix tests 2025-11-27 15:32:30 +01:00
dholle cfc419b98e .gitea/workflows/sonarqube.yml aktualisiert
SonarQube Scan / SonarQube Trigger (push) Failing after 3m18s
2025-11-27 14:16:53 +00:00
dholle 3b2df3c186 .gitea/workflows/build_and_test.yml aktualisiert
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
2025-11-27 14:16:35 +00:00
dholle ed1feda8bf revert 44d72a54e4
SonarQube Scan / SonarQube Trigger (push) Failing after 59s
revert .gitea/workflows/sonarqube.yml aktualisiert
2025-11-27 13:15:12 +00:00
dholle 44d72a54e4 .gitea/workflows/sonarqube.yml aktualisiert
SonarQube Scan / SonarQube Trigger (push) Failing after 39s
2025-11-27 13:12:22 +00:00
dholle 12f8dd162d Fix switch test
SonarQube Scan / SonarQube Trigger (push) Failing after 2m58s
2025-11-27 13:49:49 +01:00
dholle 6e37131fb2 Update to Java 25
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
2025-11-27 13:49:26 +01:00
dholle eb09117a67 Don't eat exception message
SonarQube Scan / SonarQube Trigger (push) Failing after 1m45s
2025-10-09 16:22:18 +02:00
dholle c7891b4965 Fix #383
SonarQube Scan / SonarQube Trigger (push) Failing after 1m44s
2025-10-09 15:16:21 +02:00
dholle f7891b1196 Fix FunN types decaying into the wrong base class
SonarQube Scan / SonarQube Trigger (push) Successful in 2m49s
2025-10-09 12:54:21 +02:00
dholle 1e926e4996 Don't load classes explicitly
SonarQube Scan / SonarQube Trigger (push) Successful in 2m36s
2025-10-08 17:21:20 +02:00
dholle acdaa1185b Fix #382
SonarQube Scan / SonarQube Trigger (push) Successful in 2m32s
2025-10-08 17:09:35 +02:00
dholle a20a45d7c3 Remove generic parameter from FunVoid
SonarQube Scan / SonarQube Trigger (push) Successful in 2m53s
2025-10-08 14:39:43 +02:00
dholle a68035748c Merge branch 'LSP-Interface'
SonarQube Scan / SonarQube Trigger (push) Successful in 3m42s
2025-10-02 16:14:39 +02:00
dholle 8c476b9e29 Fix #380
SonarQube Scan / SonarQube Trigger (push) Successful in 2m51s
2025-10-02 13:50:03 +02:00
dholle 6bb462cd06 Fix other test cases
SonarQube Scan / SonarQube Trigger (push) Successful in 3m11s
2025-09-30 12:28:32 +02:00
dholle 71555486b0 Change internals of Codegen to use boxed types by default
SonarQube Scan / SonarQube Trigger (push) Failing after 1m48s
Fix #379
Add a validator step, fix invalid attributes
2025-09-27 11:08:27 +02:00
dholle 4048902442 Work on #378
SonarQube Scan / SonarQube Trigger (push) Successful in 2m45s
2025-09-25 17:24:32 +02:00
Ruben 4cfc070289 surround Method with Try-Catch
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 2m23s
2025-09-23 18:21:55 +02:00
Ruben 2920dfe68f Merge branch 'master' into LSP-Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m42s
2025-09-22 15:57:55 +02:00
dholle acce38e8b1 Fix #372 by using package name
SonarQube Scan / SonarQube Trigger (push) Successful in 3m50s
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m38s
2025-09-19 12:16:26 +02:00
dholle dbd7f4fcfe Signature and Descriptor confusion resolved, fix #377
SonarQube Scan / SonarQube Trigger (push) Successful in 2m43s
2025-09-19 12:01:01 +02:00
dholle 9114642370 Undo test breakage
SonarQube Scan / SonarQube Trigger (push) Successful in 3m48s
2025-09-18 18:56:08 +02:00
dholle 8ac0f96bd6 Fix #376
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
2025-09-18 18:54:39 +02:00
Ruben c9d38728af set Target to 24
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 2m40s
2025-09-18 18:02:45 +02:00
Ruben b7fad6e3c7 delete LanguageServerInterfaceTest.java
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 30s
2025-09-18 18:00:37 +02:00
Ruben 3cb9b74df1 clean up interface
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 31s
2025-09-18 17:49:28 +02:00
Ruben effc31782f Merge remote-tracking branch 'origin/LSP-Interface' into LSP-Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 32s
2025-09-18 17:42:49 +02:00
Ruben 2a24eab9d3 Merge branch 'refs/heads/master' into LSP-Interface 2025-09-18 17:33:36 +02:00
pl@gohorb.ba-horb.de b29eb71238 Merge branch 'master' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore
SonarQube Scan / SonarQube Trigger (push) Successful in 3m40s
2025-09-18 16:43:46 +02:00
pl@gohorb.ba-horb.de e9ce071e2b modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
Die Parameter von Lambda-Ausdruecken wurden mit der Variance 1 belegt.
2025-09-18 16:39:12 +02:00
dholle 3567bae0d7 Decouple Generics from ASTToTargetAST
SonarQube Scan / SonarQube Trigger (push) Successful in 3m16s
2025-09-17 17:19:23 +02:00
Ruben a314013f40 feat: move compilation part into Language Server Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 32s
2025-09-17 11:30:35 +02:00
Ruben 37c58be1f3 initially check Syntax when opening file
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 40s
2025-09-15 13:49:25 +02:00
Ruben 24920330c6 Merge branch 'refs/heads/master' into LSP-Interface 2025-09-10 13:45:58 +02:00
Ruben bc43ea749d feat: update compiler Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 7m22s
2025-08-07 16:18:51 +02:00
dholle 9160c99cf2 README.md hinzugefügt
SonarQube Scan / SonarQube Trigger (push) Successful in 2m42s
2025-08-01 13:58:56 +00:00
dholle c72a14cab3 Add libraries to sonar
SonarQube Scan / SonarQube Trigger (push) Successful in 2m45s
2025-07-31 18:03:50 +02:00
dholle 10bb5d1d11 Typo
SonarQube Scan / SonarQube Trigger (push) Successful in 3m30s
2025-07-31 17:25:31 +02:00
dholle 2842fc5069 Readd workflow for tests on other branches
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
2025-07-31 17:24:21 +02:00
dholle 5c5e0bd1e9 split up
SonarQube Scan / SonarQube Trigger (push) Successful in 2m42s
2025-07-31 15:17:18 +02:00
dholle 3d81318e01 Different property
SonarQube Scan / SonarQube Trigger (push) Failing after 2m4s
2025-07-31 15:11:43 +02:00
dholle 53e2c20608 Debug log
SonarQube Scan / SonarQube Trigger (push) Failing after 2m12s
2025-07-31 15:03:53 +02:00
dholle 86e467fd82 Add test directory?
SonarQube Scan / SonarQube Trigger (push) Failing after 2m2s
2025-07-31 15:00:21 +02:00
dholle 25b14e9342 Fix encoding issues
SonarQube Scan / SonarQube Trigger (push) Failing after 2m39s
2025-07-31 14:53:17 +02:00
dholle d0de0b31e4 Add test metadata
SonarQube Scan / SonarQube Trigger (push) Failing after 2m49s
2025-07-31 14:42:41 +02:00
dholle dd180524b2 Remove duplicate workflow
SonarQube Scan / SonarQube Trigger (push) Successful in 2m40s
2025-07-31 14:35:04 +02:00
dholle b3744bf5f7 Fix argLine not being passed to test
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Successful in 3m4s
2025-07-31 14:22:06 +02:00
dholle fda16978c2 Correct workflow
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Successful in 3m22s
2025-07-31 14:07:03 +02:00
dholle a485cd8fa6 Add jacoco
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
2025-07-31 14:05:42 +02:00
dholle f8c708f0f4 Add classes directory
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Successful in 1m50s
2025-07-31 13:54:59 +02:00
dholle 28d9946bbb Add debug logging
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 1m7s
2025-07-31 13:51:46 +02:00
dholle 7b4ca8f177 Add src
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 1m7s
2025-07-31 13:40:42 +02:00
dholle b879d7743d Compile with maven
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 1m8s
2025-07-31 13:31:56 +02:00
dholle e26a43b400 Add project key
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 31s
2025-07-31 13:28:23 +02:00
dholle 5deed725ae Fix again
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 26s
2025-07-31 12:16:17 +02:00
dholle 8ae15f9d41 Update again
SonarQube Scan / SonarQube Trigger (push) Has been cancelled
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-07-31 12:15:11 +02:00
dholle 8c8e088612 Use newer scanner
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 20s
2025-07-31 12:06:21 +02:00
dholle 2814c6538e Add jdk 17
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m48s
SonarQube Scan / SonarQube Trigger (push) Failing after 24s
2025-07-31 11:56:58 +02:00
dholle dcbc29b49b Nano
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
SonarQube Scan / SonarQube Trigger (push) Failing after 13s
2025-07-31 11:49:01 +02:00
dholle 05033bcb9d Sonar
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-07-31 11:48:03 +02:00
Fabian Holzwarth af15a1b90c Merge branch 'master' into feat/unify-server-mergeMaster 2025-07-24 14:41:05 +02:00
dholle 814f5dd5fa Add main method #372
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m40s
2025-07-23 16:00:37 +02:00
dholle 24ca985ccc Fix #373
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m17s
2025-07-23 14:41:57 +02:00
dholle d6ed0689bc Fix test
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m33s
2025-07-23 11:56:34 +02:00
dholle d7676f36e3 Fix #371
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 1m55s
2025-07-23 11:44:10 +02:00
Fabian Holzwarth 3d99f282f5 feat: cleanup code 2025-07-21 16:12:56 +02:00
Fabian Holzwarth 303c91dc87 chore: making classnames more expressive and cleanup some structures 2025-07-19 12:50:30 +02:00
Ruben c479b044b3 feat: add Method to only get AST
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m43s
2025-07-16 14:18:22 +02:00
Ruben 9046fb09e5 fix: directly use .generate Method instead of compiling each file by hand
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 7m20s
2025-07-16 11:53:48 +02:00
julian 9e323759d6 sort resultsets before printing them to the console to enhance comparability between results
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 1m28s
2025-07-16 11:17:53 +02:00
Fabian Holzwarth 603a8b176a feat: implement partically cancellable tasks 2025-07-16 11:16:30 +02:00
dholle 558083166d Fix subtyping of function types
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 1m45s
2025-07-15 15:02:15 +02:00
julian aec2f9a399 adjust FiniteClosure to only use imported types + some necessary ones
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 1m37s
2025-07-15 14:06:51 +02:00
Fabian Holzwarth f396189a4b feat: add timestamp to server output 2025-07-12 13:44:18 +02:00
Fabian Holzwarth e7f4a94908 feat: fixed old condition on server timeout 2025-07-12 13:22:54 +02:00
Fabian Holzwarth ce49a4b9a5 feat: reduce temporary objects and repeated loops 2025-07-12 13:14:55 +02:00
Fabian Holzwarth 03b3692724 feat: update indepenedentest 2025-07-11 12:50:27 +02:00
Fabian Holzwarth f0022d2b6f feat: use presized hashMaps to reduce resizing 2025-07-11 11:22:06 +02:00
pl@gohorb.ba-horb.de 31df7a65f0 deleted: ../resources/bytecode/javFiles/Bug365a.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 10m24s
modified:   ../src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   ../src/test/java/TestComplete.java
2025-07-08 17:44:55 +02:00
pl@gohorb.ba-horb.de 185989ba62 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
+++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
@@ -73,7 +73,7 @@ public class TYPEStmt implements StatementVisitor {

     @Override
     public void visit(LambdaExpression lambdaExpression) {
-        TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
+        TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken(), -1, false);
         List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
         lambdaParams.add(tphRetType);
         // lambdaParams.add(0,tphRetType);
@@ -635,6 +635,7 @@ public class TYPEStmt implements StatementVisitor {
             params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken())));
         }
         RefTypeOrTPHOrWildcardOrGeneric receiverType;

	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
2025-07-08 14:32:05 +02:00
Fabian Holzwarth b1015cfa82 feat: update logging and add success-level 2025-07-07 16:19:04 +02:00
Fabian Holzwarth b63a27a0a0 feat: improve server by assinging configured thread pools 2025-07-07 15:59:46 +02:00
Fabian Holzwarth 3b0a53d3c4 feat: add cross dependency, fix: socket closing and error messages 2025-07-07 15:19:56 +02:00
Fabian Holzwarth 50dbbf5f86 feat: implement generalized socket client, server logger and cleanup code 2025-07-07 14:01:27 +02:00
pl@gohorb.ba-horb.de 0eb48ba425 new file: resources/bytecode/javFiles/Bug365a.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 4m44s
modified:   src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   src/test/java/TestComplete.java
2025-07-07 13:11:27 +02:00
Fabian Holzwarth 130c491ac0 feat: more Boxing replacements 2025-07-06 15:49:59 +02:00
Fabian Holzwarth 9f9b264ac4 feat: replace unnecessary boxing with primitives 2025-07-06 15:18:51 +02:00
Fabian Holzwarth 1393db05c2 feat: implement lazy evaluation for logger outputs 2025-07-06 13:37:47 +02:00
Fabian Holzwarth 93e1a8787c feat: do not create a new context, if nothing changes 2025-07-05 11:43:10 +02:00
Fabian Holzwarth 0129d7540f feat use perMessagDeflate compression in websocket and use logger for message outpute 2025-07-05 11:16:06 +02:00
Fabian Holzwarth 7ea8337aee feat: remove unused logging library 2025-07-05 11:15:33 +02:00
Fabian Holzwarth 28458d405f feat: ignore server test 2025-07-02 15:47:55 +02:00
dholle ceee9a49c4 Merge branch 'issue363' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into issue363
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 34m14s
2025-07-02 11:09:44 +02:00
dholle ee64218a5f Fix class files not generating FunN types when using jar file 2025-07-02 11:09:38 +02:00
Fabian Holzwarth 1b905cb3e2 feat: implement loggers for the rest of the compiler 2025-07-01 23:06:09 +02:00
Fabian Holzwarth d02c3583e9 feat: implement new logger into type inference code 2025-07-01 22:16:29 +02:00
Fabian Holzwarth ca98e83fd2 feat: added logger 2025-07-01 21:21:39 +02:00
dholle c50f14a4a3 .gitea/workflows/build_and_test.yml aktualisiert
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 6m52s
2025-07-01 14:35:08 +00:00
dholle 1f4250ff84 Update project to java 24, update dependencies and change api to Junit 5
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 45s
2025-07-01 15:55:58 +02:00
dholle ae41c7f19d Fix #366 2025-07-01 15:54:08 +02:00
dholle 2416c80c20 Merge branch 'issue363' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into issue363
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-07-01 13:46:19 +02:00
dholle 4cc55c0059 Add test for #366 2025-07-01 13:45:56 +02:00
Fabian Holzwarth c80a0c8596 feat: fix error by reintroducing name generator and add server tests 2025-06-30 16:42:20 +02:00
Fabian Holzwarth 2278fb1b91 feat: undo removing NameGenerator to fix errors in ast generation 2025-06-30 12:46:41 +02:00
Fabian Holzwarth 32b16cd5fd feat: replace concurrent modification with correct function call 2025-06-30 11:49:53 +02:00
Fabian Holzwarth fd30c5f63f feat: prevent reusing the placeholder registry in tests 2025-06-29 16:04:54 +02:00
Fabian Holzwarth 8bfd6ae255 feat: remove redundant lambda functions and Set-resizings 2025-06-28 14:48:43 +02:00
Fabian Holzwarth ad2dfb13bd feat: speedup toString methods by using a StringBuilder instead of String concatenation 2025-06-28 14:30:12 +02:00
Fabian Holzwarth 501633a90c feat: fix test with null methodSignatureConstraint 2025-06-28 14:06:34 +02:00
Fabian Holzwarth 4defa50ca2 feat: added version check on connecting 2025-06-25 19:48:29 +02:00
Fabian Holzwarth d65e90536a feat: replace NameGenerator with instance of PlaceholderRegistry to prevent duplicates 2025-06-25 19:15:28 +02:00
Fabian Holzwarth 3de7f1aa61 fix: try generating new placeholders only in current placeholderRegistry context to prevent duplicates 2025-06-25 17:38:56 +02:00
Fabian Holzwarth 029e40b775 feat: make packets directional and self handling 2025-06-25 17:35:49 +02:00
Fabian Holzwarth 459bfcdd5f feat: added tests for client-server communication 2025-06-23 16:13:43 +02:00
Fabian Holzwarth 02886c38ea feat: fixed error in object serialization 2025-06-23 16:13:21 +02:00
Fabian Holzwarth 57ffae0481 fix: fixed some serialization and deserialization issues 2025-06-22 15:11:49 +02:00
Fabian Holzwarth d084d74a25 feat: fixed mismatch in PairOperator serialization 2025-06-22 10:10:32 +02:00
Fabian Holzwarth cd15016f61 feat: allow subclasses when asserting values 2025-06-21 13:44:29 +02:00
Fabian Holzwarth b0e5eee25c feat: rename Object... to Serial... and move into separate classes 2025-06-21 13:40:24 +02:00
Fabian Holzwarth d1bd285be7 fix: replace reflection class check with simple string check 2025-06-21 13:23:01 +02:00
Fabian Holzwarth a902fd5bee feat: replaced HashMaps with better type safety structure 2025-06-21 12:58:45 +02:00
Fabian Holzwarth ced9fdc9f7 fix: non serialized constraitnContext 2025-06-20 19:09:33 +02:00
Fabian Holzwarth 53417bf298 feat: implement serialization and adjust packets to correct data types 2025-06-20 18:53:25 +02:00
dholle 9434facfa0 Purge generics from lambdas
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 50m14s
2025-06-20 15:43:15 +02:00
Fabian Holzwarth 2d4da03f00 feat: implementing client-server model 2025-06-18 19:58:23 +02:00
dholle 09a6b9a788 Fix lambda expression captures
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 13m35s
2025-06-18 18:31:22 +02:00
Fabian Holzwarth f7a13f5faa feat: turn UnifyContext into a record 2025-06-18 18:26:44 +02:00
Fabian Holzwarth 8fe80b4396 feat: move static placeholder generation into object 2025-06-18 17:47:29 +02:00
jschmidt 8b342c5604 the last commit message was a lie, nothing was fixed. The lambdas does not even respect the arguments it is given?
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-06-18 16:46:27 +02:00
dholle cdb93b5155 Remove ByteArrayClassLoader and fix #363
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 4m35s
2025-06-18 15:26:14 +02:00
dholle b07e848fa2 Remove print statement
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m56s
2025-06-18 13:24:59 +02:00
dholle 313cd20f36 Fix #364
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-06-18 13:24:06 +02:00
jschmidt 567fcc3b9a rename issues to bug
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m52s
2025-06-18 12:59:00 +02:00
jschmidt d9936e7197 add issue 364
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-06-18 12:55:50 +02:00
jschmidt 8f194b3102 add issue 363
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-06-18 12:48:55 +02:00
Fabian Holzwarth eb1201ae5e feat: apply future-based approach to inner cartesian loop 2025-06-09 16:49:45 +02:00
Fabian Holzwarth 963ad76593 feat: make cartesian loop computation Future-based 2025-06-09 15:30:04 +02:00
Fabian Holzwarth 1eba09e3b0 feat: change cartesian while loop into recursive 2025-06-09 15:16:09 +02:00
Fabian Holzwarth fc82125d14 feat: change TypeUnifyTask to use future-based logic 2025-06-09 14:53:37 +02:00
Fabian Holzwarth dad468368b feat: make functions unify and unify2 future-based 2025-06-09 13:14:44 +02:00
Fabian Holzwarth fdd4f3aa59 feat: implement variance-dependent calculation as Future based 2025-06-09 12:59:23 +02:00
Fabian Holzwarth a0c11b60e8 Remove unnecessary parameter and fix some parallelization 2025-06-07 16:11:34 +02:00
Fabian Holzwarth 4cddf73e6d feat: small fixes for correct parameters 2025-06-07 14:38:18 +02:00
Fabian Holzwarth 5024a02447 feat: implement unify context and prepare variance code capsulation 2025-06-07 11:53:32 +02:00
Fabian Holzwarth 6c2d97b770 chore: code cleanup 2025-05-26 15:49:01 +02:00
Fabian Holzwarth 426c2916d3 feat: remove unnecessary synchronized blocks 2025-05-26 14:40:17 +02:00
Fabian Holzwarth f722a00fbb feat: use the current thread for computation as well 2025-05-25 15:55:07 +02:00
Fabian Holzwarth 32797c9b9f feat: cleanup more cartesian product code 2025-05-24 12:43:42 +02:00
Fabian Holzwarth 87f655c85a feat: isolate constraint-filtering for one tv from computeCartesianRecursive 2025-05-23 16:10:37 +02:00
Fabian Holzwarth 613dceae1d feat: added Logger class, remove empty println start cleanup of computeCartesianRecursive 2025-05-23 14:12:25 +02:00
Fabian Holzwarth 81cac06e16 feat: add tool for merging many hash sets in parallel 2025-05-23 14:11:52 +02:00
Fabian Holzwarth a47d5bc024 feat: slightly improved placeholder name generation 2025-05-23 14:04:48 +02:00
Fabian Holzwarth e5916d455a feat: format and merge results in parallel 2025-05-19 17:05:18 +02:00
Fabian Holzwarth ebb639e72e feat: remove log flushes 2025-05-18 16:29:19 +02:00
Fabian Holzwarth f0a4a51ce6 feat: replace thread counter with thread pool 2025-05-18 15:40:31 +02:00
Fabian Holzwarth 7442880452 feat: limit placeholder generation to uppercase chars 2025-05-18 13:24:29 +02:00
Fabian Holzwarth c4dc3b4245 feat: replace random based placeholder generation with deterministic approach 2025-05-18 12:41:56 +02:00
dholle 1391206dfe Merge branch 'master' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 6m10s
2025-05-15 15:31:17 +02:00
dholle 659bf6b500 Fix warnings in test by using correct order of arguments 2025-05-15 15:31:05 +02:00
Ruben 42e31a3471 Merge branch 'master' into LSP-Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 4m49s
2025-05-13 16:01:20 +02:00
Ruben d3b3f92193 feat: make dir when /out does not exist
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2025-05-12 18:57:46 +02:00
Ruben 8208abcaea fix: exclude Files that do not end on .jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 45s
2025-05-12 18:43:10 +02:00
Ruben e4a3939ce9 test: change TEstnames
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 41s
2025-05-09 14:11:39 +02:00
Ruben d903ec0ebb test: change TEstnames
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2025-05-09 14:11:11 +02:00
Ruben 61de81cf92 feat: compile all classes in workspace
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2025-05-08 19:00:12 +02:00
Ruben 59888006e0 feat: compile all classes in workspace
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2025-05-08 18:51:25 +02:00
Ruben 94034912b4 feat: clean out file when generating Bytecode
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2025-05-08 17:51:17 +02:00
Ruben f303163118 feat: clean out file when generating Bytecode
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2025-05-08 17:10:35 +02:00
Ruben 7d99fba044 fix: update Interface for Language Server to not throw random Errors anymore
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2025-05-07 18:53:47 +02:00
Ruben 3740d34954 fix: create Path if its non existent and add Try-Catch Clause when deleting Files in Case they dont exist
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 41s
2025-05-06 15:31:27 +02:00
Ruben d8b861ea95 feat: add Method in Interface to generate Bytecode
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2025-05-06 15:10:55 +02:00
dholle 33ed22c06a Update java version
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m33s
2025-05-06 12:00:57 +00:00
dholle 70f7857661 Ignore tests that aren't working
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 41s
2025-05-06 13:51:08 +02:00
Ruben cf45ea68bd feat: include Bytecode in /out Folder
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2025-05-05 17:26:10 +02:00
Ruben be72e4d7fb feat: add Compiler Interface
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 1m6s
2025-05-05 14:34:23 +02:00
dholle 45275b6888 Merge pull request 'Fix #356' (#357) from sealedInterfacesFix into patternMatching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 44s
Reviewed-on: #357
2025-02-12 14:19:58 +00:00
dholle 2144dd9341 Working on patterns, grouping is functional now
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 44s
2025-02-05 17:09:31 +01:00
dholle 69c2bb3dc9 Work on the right grouping, looking pretty good so far
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m46s
2025-02-04 17:19:08 +01:00
dholle 3a57d5e025 Left uncommitted
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m31s
2025-01-31 16:04:22 +01:00
julian 1e37538fde Fix #356
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m7s
2025-01-26 16:18:38 +01:00
dholle 4cdd5d016c Work on pattern matching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m31s
2025-01-16 16:52:26 +01:00
dholle 4318856fa8 Fix lookup
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m20s
2024-12-12 14:21:23 +01:00
dholle 1ace099d72 Undo 2024-12-12 14:06:33 +01:00
dholle b76e1e46f0 Make the example fail
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m47s
2024-12-11 13:29:14 +01:00
dholle 09c483542d Change grouping, doesnt work yet
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m18s
2024-12-09 16:53:32 +01:00
dholle 77411973be Fix generics
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 4m30s
2024-12-04 13:57:55 +01:00
dholle d0d9c46a67 Work on constraints for parameters of generic records
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m14s
2024-12-04 12:22:26 +01:00
Ruben 24bf3d350f feat: add Generic Resolver for Records
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 4m54s
2024-11-29 13:50:09 +01:00
dholle b9f9994de3 toString() doesn't return the class name, see #353
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m18s
2024-11-27 12:57:58 +01:00
pl@gohorb.ba-horb.de f0287c4611 modified: resources/AllgemeinTest/Box.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m3s
modified:   src/test/java/AllgemeinTest.java
2024-11-25 15:46:14 +01:00
pl@gohorb.ba-horb.de edf609f916 Merge branch 'patternMatching' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into patternMatching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m39s
2024-11-24 08:15:12 +01:00
pl@gohorb.ba-horb.de 14e2af7d2a modified: resources/AllgemeinTest/Box.jav
modified:   src/test/java/AllgemeinTest.java
2024-11-24 08:15:01 +01:00
pl@gohorb.ba-horb.de 158adf837a modified: resources/bytecode/javFiles/PatternMatchingListAppend.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 4m21s
2024-11-21 14:55:52 +01:00
dholle 46b378e3a5 Fix value matching and add new test case
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m6s
2024-11-21 14:31:18 +01:00
dholle 484a70c15c Fix test case
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m10s
2024-11-20 17:22:05 +01:00
dholle c461e89336 Try to use 22 for test, might fail
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 4m45s
2024-11-20 17:03:37 +01:00
dholle f846142ee1 Add broken value matching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 40s
2024-11-20 14:44:10 +01:00
dholle 443b8b0c09 Test nested record matching, thankfully switch does the heavy lifting, fixes #349
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2024-11-20 13:17:10 +01:00
dholle ff715a22cf Filter out duplicate patterns
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2024-11-20 11:37:50 +01:00
dholle 170955b333 More complex overloading for switch
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2024-11-19 15:19:40 +01:00
dholle 88d81f4af7 Work on overloading
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 47s
2024-11-19 13:32:55 +01:00
dholle bb11d24101 First implementation of generating a bridge method
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 45s
2024-11-11 15:47:38 +01:00
dholle e2bf09548f Rename test file and some work on the overloading behavior
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 50s
2024-11-07 17:04:43 +01:00
Ruben c33e372446 feat: change Test-Case
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2024-10-25 15:58:18 +02:00
pl@gohorb.ba-horb.de 7c546834c0 modified: resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
	modified:   src/test/java/TestComplete.java
2024-10-25 15:31:48 +02:00
Ruben aa61f90fb1 feat: add Example for HaskellStyle Pattern Matching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s
2024-10-25 14:04:50 +02:00
Ruben b4da20e1d4 feat: add Example for HaskellStyle Pattern Matching 2024-10-25 14:04:03 +02:00
Ruben 4d1950d0ba feat: add Example for HaskellStyle Pattern Matching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2024-10-25 12:06:23 +02:00
pl@gohorb.ba-horb.de cc204f659a modified: resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 42s
2024-10-25 11:12:46 +02:00
pl@gohorb.ba-horb.de 5893338783 new file: resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 51s
2024-10-25 11:10:00 +02:00
dholle e1e744152a Fix overloading considering too many options, fix #348
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 44s
2024-10-11 14:13:55 +02:00
Ruben fc22299af5 feat: add Literal in Records and LPattern for Syntaxtreegenerator
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 45s
2024-10-09 17:01:28 +02:00
dholle 7811ecce63 Fix non chainable parts in dotted expression
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 49s
2024-10-04 16:41:05 +02:00
dholle 44754e73ac Remove left over example code
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m28s
2024-10-04 15:05:46 +02:00
Ruben 6ee308a712 feat: add Constraints for Records in Parameterlist
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m6s
2024-10-02 17:06:30 +02:00
dholle 85d70378ca Merge branch 'patternMatching' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into patternMatching
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m42s
2024-10-02 15:09:25 +02:00
dholle 89bbbdacd8 Work on pattern matching in function headers 2024-10-02 15:09:19 +02:00
Ruben fbde5afb1b feat: changes on Grammar for literals in Records
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2024-10-02 15:02:08 +02:00
dholle 6ccf2a3df6 Add overloading for switches, see #348
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m1s
2024-10-01 17:28:20 +02:00
dholle b7979ac7e7 Fix tests
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 7m41s
2024-09-26 11:31:24 +02:00
Ruben 9ede47c2d6 feat: add Constraint for Default-Case
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m58s
2024-09-20 18:02:53 +02:00
Ruben 406f98e55d feat: add Constraint for Default-Case 2024-09-20 18:02:13 +02:00
pl@gohorb.ba-horb.de a9d836ce25 modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m22s
modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
2024-09-19 17:43:23 +02:00
pl@gohorb.ba-horb.de fd8a66dd59 Variance und wildcardable in die Syntaxtree-Generierung verschoben
modified:   src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/PlaceholderType.java
	modified:   src/test/java/TestComplete.java
2024-09-19 17:22:51 +02:00
Ruben 929392b7d4 refactor: enhanced Constraint-Genereation
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m41s
2024-09-18 14:06:52 +02:00
Ruben f57c8aa5a9 feat: add Constraints
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2024-09-18 14:03:36 +02:00
Ruben daa38183fa feat: adding Covariance for Switch
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 4m37s
2024-09-18 13:54:01 +02:00
dholle eb454aa5b2 Add check for sealed interfaces
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m41s
2024-09-13 14:23:03 +02:00
dholle 72035c48f2 Update dependencies
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m56s
2024-09-12 14:42:09 +02:00
dholle 54f258e333 Default throws
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2024-09-12 14:36:26 +02:00
Ruben 114de0b236 refactor + test: removed comments and fixed Test-Assertion
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 4m56s
2024-09-04 11:03:11 +02:00
Ruben 8f094eb025 refactor: refactoring
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m20s
2024-09-04 10:42:11 +02:00
Ruben 3ac3af2327 test: add Test for Switch-Case with generic Records.
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 6m55s
2024-09-02 19:15:53 +02:00
dholle fbc9f1e755 Fix bugs and add new example
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m13s
2024-08-22 15:13:25 +02:00
Ruben 94c359f7a1 test & feat: recursive Method-Call for nested Constraint-Generation Patterns in Records and added Linked-List Testcase.
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 6m7s
2024-08-20 19:52:55 +02:00
Ruben 3be557a32b Merge branch 'targetBytecode' into patternMatching 2024-08-11 19:57:07 +02:00
dholle 9801f8a5ae Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2221/JavaTX/JavaCompilerCore into targetBytecode
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m39s
2024-08-07 13:34:03 +02:00
dholle f0b9bea23e Fix #343 (le null check) 2024-08-07 13:33:40 +02:00
Ruben 96eb504174 test & fix: add Testcase for Heritage-detection and removed unnecessary creation of Constraints.
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m42s
2024-08-06 18:44:52 +02:00
dholle ce4347dd96 Fix Y Test #341
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m20s
2024-08-06 12:42:09 +02:00
Ruben 4f0162ba64 Merge branch 'targetBytecode' into patternMatching 2024-08-05 15:42:48 +02:00
Ruben 6e1198ab3d test: reverted TestCodegen 2024-08-05 15:40:05 +02:00
dholle 7785c2d0aa Fix equals method of ClassOrInterface
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m48s
2024-08-05 11:54:13 +02:00
Ruben cc8f36d3ec feat: further implementation
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 7m5s
2024-08-02 18:02:35 +02:00
Ruben 139325e78f feat: fixed Commends
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 7m41s
2024-07-31 17:42:23 +02:00
Ruben b18b0a38cf feat: adding Constraints. 2024-07-31 17:41:58 +02:00
dholle a654f55deb Fix yTest
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 4m45s
2024-07-25 17:05:27 +02:00
Ruben be60261795 feat: further fixes.
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m1s
2024-07-25 08:30:52 +02:00
Ruben c7f4a2d4c1 feat: further fixes.
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2024-07-25 08:27:43 +02:00
pl@gohorb.ba-horb.de 7037bdf9ef modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 5m16s
2024-07-24 23:31:13 +02:00
pl@gohorb.ba-horb.de d9860497df Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into targetBytecode
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m38s
src/test/java/AllgemeinTest.java
2024-07-24 23:25:07 +02:00
pl@gohorb.ba-horb.de fdffc11580 modified: resources/AllgemeinTest/Box.jav
deleted:    resources/bytecode/javFiles/Box.java
	modified:   src/test/java/AllgemeinTest.java
2024-07-24 23:23:39 +02:00
pl@gohorb.ba-horb.de c10de35ca2 new file: resources/AllgemeinTest/Bar.java
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m25s
2024-07-24 18:28:07 +02:00
pl@gohorb.ba-horb.de 56b73332c0 modified: pom.xml
new file:   resources/AllgemeinTest/Foo.jav
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
2024-07-24 18:27:32 +02:00
pl@gohorb.ba-horb.de bdcd5ea3cf Merge branch 'targetBytecode' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore into targetBytecode 2024-07-24 12:35:43 +02:00
Ruben 5f944e441c feat: working with Integer-Values but not Strings.
Build and Test with Maven / Build-and-test-with-Maven (push) Has been cancelled
2024-07-17 16:41:38 +02:00
pl@gohorb.ba-horb.de 4dba867f9e Merge branch 'targetBytecode' of ssh://gitea.hb.dhbw-stuttgart.de:2222/JavaTX/JavaCompilerCore into targetBytecode 2024-06-14 11:28:05 +02:00
pl@gohorb.ba-horb.de 06caf0ff66 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2024-06-14 11:27:14 +02:00
Ruben 0d572ed9b6 feat: changes in Grammar and Parser so typeless Recs get recognised
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m20s
2024-06-06 12:16:28 +02:00
pl@gohorb.ba-horb.de 5d03995f10 Merge branch 'targetBytecode' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore into targetBytecode 2024-05-27 17:44:29 +02:00
pl@gohorb.ba-horb.de 1bc58573c7 modified: src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   src/test/java/AllgemeinTest.java
2024-05-27 17:35:59 +02:00
Pluemicke Martin 3d2b935c60 Merge branch 'targetBytecode' of https://gitea.hb.dhbw-stuttgart.de/JavaTX/JavaCompilerCore into targetBytecode 2024-05-14 22:53:08 +02:00
230 changed files with 38144 additions and 6126 deletions
+5 -2
View File
@@ -1,5 +1,8 @@
name: Build and Test with Maven name: Build and Test with Maven
on: [push] on:
push:
branches-ignore:
- master
jobs: jobs:
Build-and-test-with-Maven: Build-and-test-with-Maven:
@@ -15,7 +18,7 @@ jobs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '25'
cache: 'maven' cache: 'maven'
- name: Compile project - name: Compile project
run: | run: |
+45
View File
@@ -0,0 +1,45 @@
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
name: SonarQube Scan
jobs:
sonarqube:
name: SonarQube Trigger
runs-on: ubuntu-latest
steps:
- name: Checking out
uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: Install maven
run: |
apt update
apt install -y maven
- name: Install java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '25'
cache: 'maven'
- name: Compile project
run: |
mvn clean dependency:copy-dependencies verify
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5.3.0
env:
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }}
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
with:
args: >
-Dsonar.projectKey=Java-TX
-Dsonar.sources=src/main/java
-Dsonar.tests=src/test/java
-Dsonar.junit.reportPaths=target/test-reports
-Dsonar.java.binaries=target/classes
-Dsonar.java.libraries=target/dependency/*.jar
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
+7
View File
@@ -0,0 +1,7 @@
## Java-TX Compiler
[![Lines of Code](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=ncloc&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
[![Coverage](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=coverage&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
[![Quality Gate Status](https://gitea.hb.dhbw-stuttgart.de/sonarqube/api/project_badges/measure?project=Java-TX&metric=alert_status&token=sqb_d4a372fca7a6b86441243728a6ea5f88183db5eb)](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
Work in Progress Java-TX Compiler repository!
File diff suppressed because one or more lines are too long
+873
View File
@@ -0,0 +1,873 @@
// Generated from C:/Users/ruben/IdeaProjects/JavaCompilerCore/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Lexer.g4 by ANTLR 4.13.1
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
public class Java17Lexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
ABSTRACT=1, ASSERT=2, BOOLEAN=3, BREAK=4, BYTE=5, CASE=6, CATCH=7, CHAR=8,
CLASS=9, CONST=10, CONTINUE=11, DEFAULT=12, DO=13, DOUBLE=14, ELSE=15,
ENUM=16, EXTENDS=17, FINAL=18, FINALLY=19, FLOAT=20, FOR=21, IF=22, GOTO=23,
IMPLEMENTS=24, IMPORT=25, INSTANCEOF=26, INT=27, INTERFACE=28, LONG=29,
NATIVE=30, NEW=31, PACKAGE=32, PRIVATE=33, PROTECTED=34, PUBLIC=35, RETURN=36,
SHORT=37, STATIC=38, STRICTFP=39, SUPER=40, SWITCH=41, SYNCHRONIZED=42,
THIS=43, THROW=44, THROWS=45, TRANSIENT=46, TRY=47, VOID=48, VOLATILE=49,
WHILE=50, MODULE=51, OPEN=52, REQUIRES=53, EXPORTS=54, OPENS=55, TO=56,
USES=57, PROVIDES=58, WITH=59, TRANSITIVE=60, VAR=61, YIELD=62, RECORD=63,
SEALED=64, PERMITS=65, NON_SEALED=66, DECIMAL_LITERAL=67, HEX_LITERAL=68,
OCT_LITERAL=69, BINARY_LITERAL=70, FLOAT_LITERAL=71, HEX_FLOAT_LITERAL=72,
BOOL_LITERAL=73, CHAR_LITERAL=74, STRING_LITERAL=75, TEXT_BLOCK=76, NULL_LITERAL=77,
LPAREN=78, RPAREN=79, LBRACE=80, RBRACE=81, LBRACK=82, RBRACK=83, SEMI=84,
COMMA=85, DOT=86, ASSIGN=87, GT=88, LT=89, BANG=90, TILDE=91, QUESTION=92,
COLON=93, EQUAL=94, LE=95, GE=96, NOTEQUAL=97, AND=98, OR=99, INC=100,
DEC=101, ADD=102, SUB=103, MUL=104, DIV=105, BITAND=106, BITOR=107, CARET=108,
MOD=109, ADD_ASSIGN=110, SUB_ASSIGN=111, MUL_ASSIGN=112, DIV_ASSIGN=113,
AND_ASSIGN=114, OR_ASSIGN=115, XOR_ASSIGN=116, MOD_ASSIGN=117, LSHIFT_ASSIGN=118,
RSHIFT_ASSIGN=119, URSHIFT_ASSIGN=120, ARROW=121, COLONCOLON=122, AT=123,
ELLIPSIS=124, WS=125, COMMENT=126, LINE_COMMENT=127, IDENTIFIER=128;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR",
"CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM",
"EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO", "IMPLEMENTS",
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW",
"PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC",
"STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS",
"TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE", "OPEN", "REQUIRES",
"EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH", "TRANSITIVE", "VAR",
"YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED", "DECIMAL_LITERAL",
"HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL", "HEX_FLOAT_LITERAL",
"BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL", "TEXT_BLOCK", "NULL_LITERAL",
"LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", "SEMI", "COMMA",
"DOT", "ASSIGN", "GT", "LT", "BANG", "TILDE", "QUESTION", "COLON", "EQUAL",
"LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", "SUB", "MUL",
"DIV", "BITAND", "BITOR", "CARET", "MOD", "ADD_ASSIGN", "SUB_ASSIGN",
"MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
"MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ARROW",
"COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT", "LINE_COMMENT", "IDENTIFIER",
"ExponentPart", "EscapeSequence", "HexDigits", "HexDigit", "Digits",
"LetterOrDigit", "Letter"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, "'abstract'", "'assert'", "'boolean'", "'break'", "'byte'", "'case'",
"'catch'", "'char'", "'class'", "'const'", "'continue'", "'default'",
"'do'", "'double'", "'else'", "'enum'", "'extends'", "'final'", "'finally'",
"'float'", "'for'", "'if'", "'goto'", "'implements'", "'import'", "'instanceof'",
"'int'", "'interface'", "'long'", "'native'", "'new'", "'package'", "'private'",
"'protected'", "'public'", "'return'", "'short'", "'static'", "'strictfp'",
"'super'", "'switch'", "'synchronized'", "'this'", "'throw'", "'throws'",
"'transient'", "'try'", "'void'", "'volatile'", "'while'", "'module'",
"'open'", "'requires'", "'exports'", "'opens'", "'to'", "'uses'", "'provides'",
"'with'", "'transitive'", "'var'", "'yield'", "'record'", "'sealed'",
"'permits'", "'non-sealed'", null, null, null, null, null, null, null,
null, null, null, "'null'", "'('", "')'", "'{'", "'}'", "'['", "']'",
"';'", "','", "'.'", "'='", "'>'", "'<'", "'!'", "'~'", "'?'", "':'",
"'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", "'--'", "'+'",
"'-'", "'*'", "'/'", "'&'", "'|'", "'^'", "'%'", "'+='", "'-='", "'*='",
"'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", "'>>>='", "'->'",
"'::'", "'@'", "'...'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH",
"CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE",
"ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO",
"IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE",
"NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT",
"STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW",
"THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE",
"OPEN", "REQUIRES", "EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH",
"TRANSITIVE", "VAR", "YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED",
"DECIMAL_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL",
"HEX_FLOAT_LITERAL", "BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
"TEXT_BLOCK", "NULL_LITERAL", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
"LBRACK", "RBRACK", "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "BANG",
"TILDE", "QUESTION", "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND",
"OR", "INC", "DEC", "ADD", "SUB", "MUL", "DIV", "BITAND", "BITOR", "CARET",
"MOD", "ADD_ASSIGN", "SUB_ASSIGN", "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN",
"OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN",
"URSHIFT_ASSIGN", "ARROW", "COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT",
"LINE_COMMENT", "IDENTIFIER"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public Java17Lexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "Java17Lexer.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\u0004\u0000\u0080\u0458\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+
"\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+
"\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+
"\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+
"\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
"\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+
"\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+
"\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+
"\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+
"\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+
"\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+
"\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+
"&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+
"+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+
"0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+
"5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+
":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+
"?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+
"D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+
"I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+
"N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+
"S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+
"X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+
"]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+
"b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+
"g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+
"l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+
"q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+
"v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+
"{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+
"\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+
"\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+
"\u0002\u0086\u0007\u0086\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
"\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
"\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
"\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
"\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+
"\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+
"\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+
"\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
"\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
"\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\r\u0001"+
"\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001"+
"\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
"\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
"\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001"+
"\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+
"\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001"+
"\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001"+
"\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001"+
"\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001"+
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001"+
"\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001"+
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001"+
"\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
"\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
"\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001"+
"\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001"+
"\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001"+
"\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001"+
"\u001f\u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001!"+
"\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001"+
"\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+
"#\u0001#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0001$\u0001"+
"$\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001"+
"&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001"+
"\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001"+
")\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001"+
")\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001"+
"+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001"+
",\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001"+
"-\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u0001/\u0001/\u0001/\u0001"+
"0\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00011\u0001"+
"1\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00012\u0001"+
"2\u00012\u00013\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u0001"+
"4\u00014\u00014\u00014\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+
"5\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u00016\u00016\u0001"+
"7\u00017\u00017\u00018\u00018\u00018\u00018\u00018\u00019\u00019\u0001"+
"9\u00019\u00019\u00019\u00019\u00019\u00019\u0001:\u0001:\u0001:\u0001"+
":\u0001:\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001"+
";\u0001;\u0001;\u0001<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001"+
"=\u0001=\u0001=\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001"+
"?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001"+
"@\u0001@\u0001@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001A\u0001"+
"A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0003B\u02d5"+
"\bB\u0001B\u0004B\u02d8\bB\u000bB\fB\u02d9\u0001B\u0003B\u02dd\bB\u0003"+
"B\u02df\bB\u0001B\u0003B\u02e2\bB\u0001C\u0001C\u0001C\u0001C\u0005C\u02e8"+
"\bC\nC\fC\u02eb\tC\u0001C\u0003C\u02ee\bC\u0001C\u0003C\u02f1\bC\u0001"+
"D\u0001D\u0005D\u02f5\bD\nD\fD\u02f8\tD\u0001D\u0001D\u0005D\u02fc\bD"+
"\nD\fD\u02ff\tD\u0001D\u0003D\u0302\bD\u0001D\u0003D\u0305\bD\u0001E\u0001"+
"E\u0001E\u0001E\u0005E\u030b\bE\nE\fE\u030e\tE\u0001E\u0003E\u0311\bE"+
"\u0001E\u0003E\u0314\bE\u0001F\u0001F\u0001F\u0003F\u0319\bF\u0001F\u0001"+
"F\u0003F\u031d\bF\u0001F\u0003F\u0320\bF\u0001F\u0003F\u0323\bF\u0001"+
"F\u0001F\u0001F\u0003F\u0328\bF\u0001F\u0003F\u032b\bF\u0003F\u032d\b"+
"F\u0001G\u0001G\u0001G\u0001G\u0003G\u0333\bG\u0001G\u0003G\u0336\bG\u0001"+
"G\u0001G\u0003G\u033a\bG\u0001G\u0001G\u0003G\u033e\bG\u0001G\u0001G\u0003"+
"G\u0342\bG\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001"+
"H\u0003H\u034d\bH\u0001I\u0001I\u0001I\u0003I\u0352\bI\u0001I\u0001I\u0001"+
"J\u0001J\u0001J\u0005J\u0359\bJ\nJ\fJ\u035c\tJ\u0001J\u0001J\u0001K\u0001"+
"K\u0001K\u0001K\u0001K\u0005K\u0365\bK\nK\fK\u0368\tK\u0001K\u0001K\u0001"+
"K\u0005K\u036d\bK\nK\fK\u0370\tK\u0001K\u0001K\u0001K\u0001K\u0001L\u0001"+
"L\u0001L\u0001L\u0001L\u0001M\u0001M\u0001N\u0001N\u0001O\u0001O\u0001"+
"P\u0001P\u0001Q\u0001Q\u0001R\u0001R\u0001S\u0001S\u0001T\u0001T\u0001"+
"U\u0001U\u0001V\u0001V\u0001W\u0001W\u0001X\u0001X\u0001Y\u0001Y\u0001"+
"Z\u0001Z\u0001[\u0001[\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001^\u0001"+
"^\u0001^\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001a\u0001a\u0001"+
"a\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001d\u0001d\u0001d\u0001"+
"e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001i\u0001"+
"j\u0001j\u0001k\u0001k\u0001l\u0001l\u0001m\u0001m\u0001m\u0001n\u0001"+
"n\u0001n\u0001o\u0001o\u0001o\u0001p\u0001p\u0001p\u0001q\u0001q\u0001"+
"q\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001"+
"u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001"+
"w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001"+
"z\u0001{\u0001{\u0001{\u0001{\u0001|\u0004|\u03f5\b|\u000b|\f|\u03f6\u0001"+
"|\u0001|\u0001}\u0001}\u0001}\u0001}\u0005}\u03ff\b}\n}\f}\u0402\t}\u0001"+
"}\u0001}\u0001}\u0001}\u0001}\u0001~\u0001~\u0001~\u0001~\u0005~\u040d"+
"\b~\n~\f~\u0410\t~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0005\u007f\u0416"+
"\b\u007f\n\u007f\f\u007f\u0419\t\u007f\u0001\u0080\u0001\u0080\u0003\u0080"+
"\u041d\b\u0080\u0001\u0080\u0001\u0080\u0001\u0081\u0001\u0081\u0001\u0081"+
"\u0001\u0081\u0003\u0081\u0425\b\u0081\u0001\u0081\u0003\u0081\u0428\b"+
"\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0004\u0081\u042d\b\u0081\u000b"+
"\u0081\f\u0081\u042e\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001"+
"\u0081\u0003\u0081\u0436\b\u0081\u0001\u0082\u0001\u0082\u0001\u0082\u0005"+
"\u0082\u043b\b\u0082\n\u0082\f\u0082\u043e\t\u0082\u0001\u0082\u0003\u0082"+
"\u0441\b\u0082\u0001\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0005\u0084"+
"\u0447\b\u0084\n\u0084\f\u0084\u044a\t\u0084\u0001\u0084\u0003\u0084\u044d"+
"\b\u0084\u0001\u0085\u0001\u0085\u0003\u0085\u0451\b\u0085\u0001\u0086"+
"\u0001\u0086\u0001\u0086\u0001\u0086\u0003\u0086\u0457\b\u0086\u0002\u036e"+
"\u0400\u0000\u0087\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005"+
"\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017\f\u0019"+
"\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'\u0014)\u0015"+
"+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d;\u001e=\u001f"+
"? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e3g4i5k6m7o8q9s:u;w<y={>}?\u007f"+
"@\u0081A\u0083B\u0085C\u0087D\u0089E\u008bF\u008dG\u008fH\u0091I\u0093"+
"J\u0095K\u0097L\u0099M\u009bN\u009dO\u009fP\u00a1Q\u00a3R\u00a5S\u00a7"+
"T\u00a9U\u00abV\u00adW\u00afX\u00b1Y\u00b3Z\u00b5[\u00b7\\\u00b9]\u00bb"+
"^\u00bd_\u00bf`\u00c1a\u00c3b\u00c5c\u00c7d\u00c9e\u00cbf\u00cdg\u00cf"+
"h\u00d1i\u00d3j\u00d5k\u00d7l\u00d9m\u00dbn\u00ddo\u00dfp\u00e1q\u00e3"+
"r\u00e5s\u00e7t\u00e9u\u00ebv\u00edw\u00efx\u00f1y\u00f3z\u00f5{\u00f7"+
"|\u00f9}\u00fb~\u00fd\u007f\u00ff\u0080\u0101\u0000\u0103\u0000\u0105"+
"\u0000\u0107\u0000\u0109\u0000\u010b\u0000\u010d\u0000\u0001\u0000\u001b"+
"\u0001\u000019\u0002\u0000LLll\u0002\u0000XXxx\u0003\u000009AFaf\u0004"+
"\u000009AF__af\u0001\u000007\u0002\u000007__\u0002\u0000BBbb\u0001\u0000"+
"01\u0002\u000001__\u0004\u0000DDFFddff\u0002\u0000PPpp\u0002\u0000++-"+
"-\u0004\u0000\n\n\r\r\'\'\\\\\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000"+
"\t\t \u0002\u0000\n\n\r\r\u0003\u0000\t\n\f\r \u0002\u0000EEee\b\u0000"+
"\"\"\'\'\\\\bbffnnrrtt\u0001\u000003\u0001\u000009\u0002\u000009__\u0004"+
"\u0000$$AZ__az\u0002\u0000\u0000\u007f\u8000\ud800\u8000\udbff\u0001\u0000"+
"\u8000\ud800\u8000\udbff\u0001\u0000\u8000\udc00\u8000\udfff\u0484\u0000"+
"\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000"+
"\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000"+
"\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r"+
"\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011"+
"\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015"+
"\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019"+
"\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d"+
"\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001"+
"\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000"+
"\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000"+
"\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/"+
"\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000"+
"\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000"+
"\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000="+
"\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000A\u0001\u0000"+
"\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001\u0000\u0000\u0000"+
"\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000\u0000\u0000K"+
"\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000O\u0001\u0000"+
"\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001\u0000\u0000\u0000"+
"\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000\u0000Y"+
"\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000]\u0001\u0000"+
"\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0000a\u0001\u0000\u0000\u0000"+
"\u0000c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000\u0000\u0000g"+
"\u0001\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0000k\u0001\u0000"+
"\u0000\u0000\u0000m\u0001\u0000\u0000\u0000\u0000o\u0001\u0000\u0000\u0000"+
"\u0000q\u0001\u0000\u0000\u0000\u0000s\u0001\u0000\u0000\u0000\u0000u"+
"\u0001\u0000\u0000\u0000\u0000w\u0001\u0000\u0000\u0000\u0000y\u0001\u0000"+
"\u0000\u0000\u0000{\u0001\u0000\u0000\u0000\u0000}\u0001\u0000\u0000\u0000"+
"\u0000\u007f\u0001\u0000\u0000\u0000\u0000\u0081\u0001\u0000\u0000\u0000"+
"\u0000\u0083\u0001\u0000\u0000\u0000\u0000\u0085\u0001\u0000\u0000\u0000"+
"\u0000\u0087\u0001\u0000\u0000\u0000\u0000\u0089\u0001\u0000\u0000\u0000"+
"\u0000\u008b\u0001\u0000\u0000\u0000\u0000\u008d\u0001\u0000\u0000\u0000"+
"\u0000\u008f\u0001\u0000\u0000\u0000\u0000\u0091\u0001\u0000\u0000\u0000"+
"\u0000\u0093\u0001\u0000\u0000\u0000\u0000\u0095\u0001\u0000\u0000\u0000"+
"\u0000\u0097\u0001\u0000\u0000\u0000\u0000\u0099\u0001\u0000\u0000\u0000"+
"\u0000\u009b\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000\u0000"+
"\u0000\u009f\u0001\u0000\u0000\u0000\u0000\u00a1\u0001\u0000\u0000\u0000"+
"\u0000\u00a3\u0001\u0000\u0000\u0000\u0000\u00a5\u0001\u0000\u0000\u0000"+
"\u0000\u00a7\u0001\u0000\u0000\u0000\u0000\u00a9\u0001\u0000\u0000\u0000"+
"\u0000\u00ab\u0001\u0000\u0000\u0000\u0000\u00ad\u0001\u0000\u0000\u0000"+
"\u0000\u00af\u0001\u0000\u0000\u0000\u0000\u00b1\u0001\u0000\u0000\u0000"+
"\u0000\u00b3\u0001\u0000\u0000\u0000\u0000\u00b5\u0001\u0000\u0000\u0000"+
"\u0000\u00b7\u0001\u0000\u0000\u0000\u0000\u00b9\u0001\u0000\u0000\u0000"+
"\u0000\u00bb\u0001\u0000\u0000\u0000\u0000\u00bd\u0001\u0000\u0000\u0000"+
"\u0000\u00bf\u0001\u0000\u0000\u0000\u0000\u00c1\u0001\u0000\u0000\u0000"+
"\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000\u0000"+
"\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000\u0000"+
"\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000\u0000"+
"\u0000\u00cf\u0001\u0000\u0000\u0000\u0000\u00d1\u0001\u0000\u0000\u0000"+
"\u0000\u00d3\u0001\u0000\u0000\u0000\u0000\u00d5\u0001\u0000\u0000\u0000"+
"\u0000\u00d7\u0001\u0000\u0000\u0000\u0000\u00d9\u0001\u0000\u0000\u0000"+
"\u0000\u00db\u0001\u0000\u0000\u0000\u0000\u00dd\u0001\u0000\u0000\u0000"+
"\u0000\u00df\u0001\u0000\u0000\u0000\u0000\u00e1\u0001\u0000\u0000\u0000"+
"\u0000\u00e3\u0001\u0000\u0000\u0000\u0000\u00e5\u0001\u0000\u0000\u0000"+
"\u0000\u00e7\u0001\u0000\u0000\u0000\u0000\u00e9\u0001\u0000\u0000\u0000"+
"\u0000\u00eb\u0001\u0000\u0000\u0000\u0000\u00ed\u0001\u0000\u0000\u0000"+
"\u0000\u00ef\u0001\u0000\u0000\u0000\u0000\u00f1\u0001\u0000\u0000\u0000"+
"\u0000\u00f3\u0001\u0000\u0000\u0000\u0000\u00f5\u0001\u0000\u0000\u0000"+
"\u0000\u00f7\u0001\u0000\u0000\u0000\u0000\u00f9\u0001\u0000\u0000\u0000"+
"\u0000\u00fb\u0001\u0000\u0000\u0000\u0000\u00fd\u0001\u0000\u0000\u0000"+
"\u0000\u00ff\u0001\u0000\u0000\u0000\u0001\u010f\u0001\u0000\u0000\u0000"+
"\u0003\u0118\u0001\u0000\u0000\u0000\u0005\u011f\u0001\u0000\u0000\u0000"+
"\u0007\u0127\u0001\u0000\u0000\u0000\t\u012d\u0001\u0000\u0000\u0000\u000b"+
"\u0132\u0001\u0000\u0000\u0000\r\u0137\u0001\u0000\u0000\u0000\u000f\u013d"+
"\u0001\u0000\u0000\u0000\u0011\u0142\u0001\u0000\u0000\u0000\u0013\u0148"+
"\u0001\u0000\u0000\u0000\u0015\u014e\u0001\u0000\u0000\u0000\u0017\u0157"+
"\u0001\u0000\u0000\u0000\u0019\u015f\u0001\u0000\u0000\u0000\u001b\u0162"+
"\u0001\u0000\u0000\u0000\u001d\u0169\u0001\u0000\u0000\u0000\u001f\u016e"+
"\u0001\u0000\u0000\u0000!\u0173\u0001\u0000\u0000\u0000#\u017b\u0001\u0000"+
"\u0000\u0000%\u0181\u0001\u0000\u0000\u0000\'\u0189\u0001\u0000\u0000"+
"\u0000)\u018f\u0001\u0000\u0000\u0000+\u0193\u0001\u0000\u0000\u0000-"+
"\u0196\u0001\u0000\u0000\u0000/\u019b\u0001\u0000\u0000\u00001\u01a6\u0001"+
"\u0000\u0000\u00003\u01ad\u0001\u0000\u0000\u00005\u01b8\u0001\u0000\u0000"+
"\u00007\u01bc\u0001\u0000\u0000\u00009\u01c6\u0001\u0000\u0000\u0000;"+
"\u01cb\u0001\u0000\u0000\u0000=\u01d2\u0001\u0000\u0000\u0000?\u01d6\u0001"+
"\u0000\u0000\u0000A\u01de\u0001\u0000\u0000\u0000C\u01e6\u0001\u0000\u0000"+
"\u0000E\u01f0\u0001\u0000\u0000\u0000G\u01f7\u0001\u0000\u0000\u0000I"+
"\u01fe\u0001\u0000\u0000\u0000K\u0204\u0001\u0000\u0000\u0000M\u020b\u0001"+
"\u0000\u0000\u0000O\u0214\u0001\u0000\u0000\u0000Q\u021a\u0001\u0000\u0000"+
"\u0000S\u0221\u0001\u0000\u0000\u0000U\u022e\u0001\u0000\u0000\u0000W"+
"\u0233\u0001\u0000\u0000\u0000Y\u0239\u0001\u0000\u0000\u0000[\u0240\u0001"+
"\u0000\u0000\u0000]\u024a\u0001\u0000\u0000\u0000_\u024e\u0001\u0000\u0000"+
"\u0000a\u0253\u0001\u0000\u0000\u0000c\u025c\u0001\u0000\u0000\u0000e"+
"\u0262\u0001\u0000\u0000\u0000g\u0269\u0001\u0000\u0000\u0000i\u026e\u0001"+
"\u0000\u0000\u0000k\u0277\u0001\u0000\u0000\u0000m\u027f\u0001\u0000\u0000"+
"\u0000o\u0285\u0001\u0000\u0000\u0000q\u0288\u0001\u0000\u0000\u0000s"+
"\u028d\u0001\u0000\u0000\u0000u\u0296\u0001\u0000\u0000\u0000w\u029b\u0001"+
"\u0000\u0000\u0000y\u02a6\u0001\u0000\u0000\u0000{\u02aa\u0001\u0000\u0000"+
"\u0000}\u02b0\u0001\u0000\u0000\u0000\u007f\u02b7\u0001\u0000\u0000\u0000"+
"\u0081\u02be\u0001\u0000\u0000\u0000\u0083\u02c6\u0001\u0000\u0000\u0000"+
"\u0085\u02de\u0001\u0000\u0000\u0000\u0087\u02e3\u0001\u0000\u0000\u0000"+
"\u0089\u02f2\u0001\u0000\u0000\u0000\u008b\u0306\u0001\u0000\u0000\u0000"+
"\u008d\u032c\u0001\u0000\u0000\u0000\u008f\u032e\u0001\u0000\u0000\u0000"+
"\u0091\u034c\u0001\u0000\u0000\u0000\u0093\u034e\u0001\u0000\u0000\u0000"+
"\u0095\u0355\u0001\u0000\u0000\u0000\u0097\u035f\u0001\u0000\u0000\u0000"+
"\u0099\u0375\u0001\u0000\u0000\u0000\u009b\u037a\u0001\u0000\u0000\u0000"+
"\u009d\u037c\u0001\u0000\u0000\u0000\u009f\u037e\u0001\u0000\u0000\u0000"+
"\u00a1\u0380\u0001\u0000\u0000\u0000\u00a3\u0382\u0001\u0000\u0000\u0000"+
"\u00a5\u0384\u0001\u0000\u0000\u0000\u00a7\u0386\u0001\u0000\u0000\u0000"+
"\u00a9\u0388\u0001\u0000\u0000\u0000\u00ab\u038a\u0001\u0000\u0000\u0000"+
"\u00ad\u038c\u0001\u0000\u0000\u0000\u00af\u038e\u0001\u0000\u0000\u0000"+
"\u00b1\u0390\u0001\u0000\u0000\u0000\u00b3\u0392\u0001\u0000\u0000\u0000"+
"\u00b5\u0394\u0001\u0000\u0000\u0000\u00b7\u0396\u0001\u0000\u0000\u0000"+
"\u00b9\u0398\u0001\u0000\u0000\u0000\u00bb\u039a\u0001\u0000\u0000\u0000"+
"\u00bd\u039d\u0001\u0000\u0000\u0000\u00bf\u03a0\u0001\u0000\u0000\u0000"+
"\u00c1\u03a3\u0001\u0000\u0000\u0000\u00c3\u03a6\u0001\u0000\u0000\u0000"+
"\u00c5\u03a9\u0001\u0000\u0000\u0000\u00c7\u03ac\u0001\u0000\u0000\u0000"+
"\u00c9\u03af\u0001\u0000\u0000\u0000\u00cb\u03b2\u0001\u0000\u0000\u0000"+
"\u00cd\u03b4\u0001\u0000\u0000\u0000\u00cf\u03b6\u0001\u0000\u0000\u0000"+
"\u00d1\u03b8\u0001\u0000\u0000\u0000\u00d3\u03ba\u0001\u0000\u0000\u0000"+
"\u00d5\u03bc\u0001\u0000\u0000\u0000\u00d7\u03be\u0001\u0000\u0000\u0000"+
"\u00d9\u03c0\u0001\u0000\u0000\u0000\u00db\u03c2\u0001\u0000\u0000\u0000"+
"\u00dd\u03c5\u0001\u0000\u0000\u0000\u00df\u03c8\u0001\u0000\u0000\u0000"+
"\u00e1\u03cb\u0001\u0000\u0000\u0000\u00e3\u03ce\u0001\u0000\u0000\u0000"+
"\u00e5\u03d1\u0001\u0000\u0000\u0000\u00e7\u03d4\u0001\u0000\u0000\u0000"+
"\u00e9\u03d7\u0001\u0000\u0000\u0000\u00eb\u03da\u0001\u0000\u0000\u0000"+
"\u00ed\u03de\u0001\u0000\u0000\u0000\u00ef\u03e2\u0001\u0000\u0000\u0000"+
"\u00f1\u03e7\u0001\u0000\u0000\u0000\u00f3\u03ea\u0001\u0000\u0000\u0000"+
"\u00f5\u03ed\u0001\u0000\u0000\u0000\u00f7\u03ef\u0001\u0000\u0000\u0000"+
"\u00f9\u03f4\u0001\u0000\u0000\u0000\u00fb\u03fa\u0001\u0000\u0000\u0000"+
"\u00fd\u0408\u0001\u0000\u0000\u0000\u00ff\u0413\u0001\u0000\u0000\u0000"+
"\u0101\u041a\u0001\u0000\u0000\u0000\u0103\u0435\u0001\u0000\u0000\u0000"+
"\u0105\u0437\u0001\u0000\u0000\u0000\u0107\u0442\u0001\u0000\u0000\u0000"+
"\u0109\u0444\u0001\u0000\u0000\u0000\u010b\u0450\u0001\u0000\u0000\u0000"+
"\u010d\u0456\u0001\u0000\u0000\u0000\u010f\u0110\u0005a\u0000\u0000\u0110"+
"\u0111\u0005b\u0000\u0000\u0111\u0112\u0005s\u0000\u0000\u0112\u0113\u0005"+
"t\u0000\u0000\u0113\u0114\u0005r\u0000\u0000\u0114\u0115\u0005a\u0000"+
"\u0000\u0115\u0116\u0005c\u0000\u0000\u0116\u0117\u0005t\u0000\u0000\u0117"+
"\u0002\u0001\u0000\u0000\u0000\u0118\u0119\u0005a\u0000\u0000\u0119\u011a"+
"\u0005s\u0000\u0000\u011a\u011b\u0005s\u0000\u0000\u011b\u011c\u0005e"+
"\u0000\u0000\u011c\u011d\u0005r\u0000\u0000\u011d\u011e\u0005t\u0000\u0000"+
"\u011e\u0004\u0001\u0000\u0000\u0000\u011f\u0120\u0005b\u0000\u0000\u0120"+
"\u0121\u0005o\u0000\u0000\u0121\u0122\u0005o\u0000\u0000\u0122\u0123\u0005"+
"l\u0000\u0000\u0123\u0124\u0005e\u0000\u0000\u0124\u0125\u0005a\u0000"+
"\u0000\u0125\u0126\u0005n\u0000\u0000\u0126\u0006\u0001\u0000\u0000\u0000"+
"\u0127\u0128\u0005b\u0000\u0000\u0128\u0129\u0005r\u0000\u0000\u0129\u012a"+
"\u0005e\u0000\u0000\u012a\u012b\u0005a\u0000\u0000\u012b\u012c\u0005k"+
"\u0000\u0000\u012c\b\u0001\u0000\u0000\u0000\u012d\u012e\u0005b\u0000"+
"\u0000\u012e\u012f\u0005y\u0000\u0000\u012f\u0130\u0005t\u0000\u0000\u0130"+
"\u0131\u0005e\u0000\u0000\u0131\n\u0001\u0000\u0000\u0000\u0132\u0133"+
"\u0005c\u0000\u0000\u0133\u0134\u0005a\u0000\u0000\u0134\u0135\u0005s"+
"\u0000\u0000\u0135\u0136\u0005e\u0000\u0000\u0136\f\u0001\u0000\u0000"+
"\u0000\u0137\u0138\u0005c\u0000\u0000\u0138\u0139\u0005a\u0000\u0000\u0139"+
"\u013a\u0005t\u0000\u0000\u013a\u013b\u0005c\u0000\u0000\u013b\u013c\u0005"+
"h\u0000\u0000\u013c\u000e\u0001\u0000\u0000\u0000\u013d\u013e\u0005c\u0000"+
"\u0000\u013e\u013f\u0005h\u0000\u0000\u013f\u0140\u0005a\u0000\u0000\u0140"+
"\u0141\u0005r\u0000\u0000\u0141\u0010\u0001\u0000\u0000\u0000\u0142\u0143"+
"\u0005c\u0000\u0000\u0143\u0144\u0005l\u0000\u0000\u0144\u0145\u0005a"+
"\u0000\u0000\u0145\u0146\u0005s\u0000\u0000\u0146\u0147\u0005s\u0000\u0000"+
"\u0147\u0012\u0001\u0000\u0000\u0000\u0148\u0149\u0005c\u0000\u0000\u0149"+
"\u014a\u0005o\u0000\u0000\u014a\u014b\u0005n\u0000\u0000\u014b\u014c\u0005"+
"s\u0000\u0000\u014c\u014d\u0005t\u0000\u0000\u014d\u0014\u0001\u0000\u0000"+
"\u0000\u014e\u014f\u0005c\u0000\u0000\u014f\u0150\u0005o\u0000\u0000\u0150"+
"\u0151\u0005n\u0000\u0000\u0151\u0152\u0005t\u0000\u0000\u0152\u0153\u0005"+
"i\u0000\u0000\u0153\u0154\u0005n\u0000\u0000\u0154\u0155\u0005u\u0000"+
"\u0000\u0155\u0156\u0005e\u0000\u0000\u0156\u0016\u0001\u0000\u0000\u0000"+
"\u0157\u0158\u0005d\u0000\u0000\u0158\u0159\u0005e\u0000\u0000\u0159\u015a"+
"\u0005f\u0000\u0000\u015a\u015b\u0005a\u0000\u0000\u015b\u015c\u0005u"+
"\u0000\u0000\u015c\u015d\u0005l\u0000\u0000\u015d\u015e\u0005t\u0000\u0000"+
"\u015e\u0018\u0001\u0000\u0000\u0000\u015f\u0160\u0005d\u0000\u0000\u0160"+
"\u0161\u0005o\u0000\u0000\u0161\u001a\u0001\u0000\u0000\u0000\u0162\u0163"+
"\u0005d\u0000\u0000\u0163\u0164\u0005o\u0000\u0000\u0164\u0165\u0005u"+
"\u0000\u0000\u0165\u0166\u0005b\u0000\u0000\u0166\u0167\u0005l\u0000\u0000"+
"\u0167\u0168\u0005e\u0000\u0000\u0168\u001c\u0001\u0000\u0000\u0000\u0169"+
"\u016a\u0005e\u0000\u0000\u016a\u016b\u0005l\u0000\u0000\u016b\u016c\u0005"+
"s\u0000\u0000\u016c\u016d\u0005e\u0000\u0000\u016d\u001e\u0001\u0000\u0000"+
"\u0000\u016e\u016f\u0005e\u0000\u0000\u016f\u0170\u0005n\u0000\u0000\u0170"+
"\u0171\u0005u\u0000\u0000\u0171\u0172\u0005m\u0000\u0000\u0172 \u0001"+
"\u0000\u0000\u0000\u0173\u0174\u0005e\u0000\u0000\u0174\u0175\u0005x\u0000"+
"\u0000\u0175\u0176\u0005t\u0000\u0000\u0176\u0177\u0005e\u0000\u0000\u0177"+
"\u0178\u0005n\u0000\u0000\u0178\u0179\u0005d\u0000\u0000\u0179\u017a\u0005"+
"s\u0000\u0000\u017a\"\u0001\u0000\u0000\u0000\u017b\u017c\u0005f\u0000"+
"\u0000\u017c\u017d\u0005i\u0000\u0000\u017d\u017e\u0005n\u0000\u0000\u017e"+
"\u017f\u0005a\u0000\u0000\u017f\u0180\u0005l\u0000\u0000\u0180$\u0001"+
"\u0000\u0000\u0000\u0181\u0182\u0005f\u0000\u0000\u0182\u0183\u0005i\u0000"+
"\u0000\u0183\u0184\u0005n\u0000\u0000\u0184\u0185\u0005a\u0000\u0000\u0185"+
"\u0186\u0005l\u0000\u0000\u0186\u0187\u0005l\u0000\u0000\u0187\u0188\u0005"+
"y\u0000\u0000\u0188&\u0001\u0000\u0000\u0000\u0189\u018a\u0005f\u0000"+
"\u0000\u018a\u018b\u0005l\u0000\u0000\u018b\u018c\u0005o\u0000\u0000\u018c"+
"\u018d\u0005a\u0000\u0000\u018d\u018e\u0005t\u0000\u0000\u018e(\u0001"+
"\u0000\u0000\u0000\u018f\u0190\u0005f\u0000\u0000\u0190\u0191\u0005o\u0000"+
"\u0000\u0191\u0192\u0005r\u0000\u0000\u0192*\u0001\u0000\u0000\u0000\u0193"+
"\u0194\u0005i\u0000\u0000\u0194\u0195\u0005f\u0000\u0000\u0195,\u0001"+
"\u0000\u0000\u0000\u0196\u0197\u0005g\u0000\u0000\u0197\u0198\u0005o\u0000"+
"\u0000\u0198\u0199\u0005t\u0000\u0000\u0199\u019a\u0005o\u0000\u0000\u019a"+
".\u0001\u0000\u0000\u0000\u019b\u019c\u0005i\u0000\u0000\u019c\u019d\u0005"+
"m\u0000\u0000\u019d\u019e\u0005p\u0000\u0000\u019e\u019f\u0005l\u0000"+
"\u0000\u019f\u01a0\u0005e\u0000\u0000\u01a0\u01a1\u0005m\u0000\u0000\u01a1"+
"\u01a2\u0005e\u0000\u0000\u01a2\u01a3\u0005n\u0000\u0000\u01a3\u01a4\u0005"+
"t\u0000\u0000\u01a4\u01a5\u0005s\u0000\u0000\u01a50\u0001\u0000\u0000"+
"\u0000\u01a6\u01a7\u0005i\u0000\u0000\u01a7\u01a8\u0005m\u0000\u0000\u01a8"+
"\u01a9\u0005p\u0000\u0000\u01a9\u01aa\u0005o\u0000\u0000\u01aa\u01ab\u0005"+
"r\u0000\u0000\u01ab\u01ac\u0005t\u0000\u0000\u01ac2\u0001\u0000\u0000"+
"\u0000\u01ad\u01ae\u0005i\u0000\u0000\u01ae\u01af\u0005n\u0000\u0000\u01af"+
"\u01b0\u0005s\u0000\u0000\u01b0\u01b1\u0005t\u0000\u0000\u01b1\u01b2\u0005"+
"a\u0000\u0000\u01b2\u01b3\u0005n\u0000\u0000\u01b3\u01b4\u0005c\u0000"+
"\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0005o\u0000\u0000\u01b6"+
"\u01b7\u0005f\u0000\u0000\u01b74\u0001\u0000\u0000\u0000\u01b8\u01b9\u0005"+
"i\u0000\u0000\u01b9\u01ba\u0005n\u0000\u0000\u01ba\u01bb\u0005t\u0000"+
"\u0000\u01bb6\u0001\u0000\u0000\u0000\u01bc\u01bd\u0005i\u0000\u0000\u01bd"+
"\u01be\u0005n\u0000\u0000\u01be\u01bf\u0005t\u0000\u0000\u01bf\u01c0\u0005"+
"e\u0000\u0000\u01c0\u01c1\u0005r\u0000\u0000\u01c1\u01c2\u0005f\u0000"+
"\u0000\u01c2\u01c3\u0005a\u0000\u0000\u01c3\u01c4\u0005c\u0000\u0000\u01c4"+
"\u01c5\u0005e\u0000\u0000\u01c58\u0001\u0000\u0000\u0000\u01c6\u01c7\u0005"+
"l\u0000\u0000\u01c7\u01c8\u0005o\u0000\u0000\u01c8\u01c9\u0005n\u0000"+
"\u0000\u01c9\u01ca\u0005g\u0000\u0000\u01ca:\u0001\u0000\u0000\u0000\u01cb"+
"\u01cc\u0005n\u0000\u0000\u01cc\u01cd\u0005a\u0000\u0000\u01cd\u01ce\u0005"+
"t\u0000\u0000\u01ce\u01cf\u0005i\u0000\u0000\u01cf\u01d0\u0005v\u0000"+
"\u0000\u01d0\u01d1\u0005e\u0000\u0000\u01d1<\u0001\u0000\u0000\u0000\u01d2"+
"\u01d3\u0005n\u0000\u0000\u01d3\u01d4\u0005e\u0000\u0000\u01d4\u01d5\u0005"+
"w\u0000\u0000\u01d5>\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005p\u0000"+
"\u0000\u01d7\u01d8\u0005a\u0000\u0000\u01d8\u01d9\u0005c\u0000\u0000\u01d9"+
"\u01da\u0005k\u0000\u0000\u01da\u01db\u0005a\u0000\u0000\u01db\u01dc\u0005"+
"g\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01dd@\u0001\u0000\u0000"+
"\u0000\u01de\u01df\u0005p\u0000\u0000\u01df\u01e0\u0005r\u0000\u0000\u01e0"+
"\u01e1\u0005i\u0000\u0000\u01e1\u01e2\u0005v\u0000\u0000\u01e2\u01e3\u0005"+
"a\u0000\u0000\u01e3\u01e4\u0005t\u0000\u0000\u01e4\u01e5\u0005e\u0000"+
"\u0000\u01e5B\u0001\u0000\u0000\u0000\u01e6\u01e7\u0005p\u0000\u0000\u01e7"+
"\u01e8\u0005r\u0000\u0000\u01e8\u01e9\u0005o\u0000\u0000\u01e9\u01ea\u0005"+
"t\u0000\u0000\u01ea\u01eb\u0005e\u0000\u0000\u01eb\u01ec\u0005c\u0000"+
"\u0000\u01ec\u01ed\u0005t\u0000\u0000\u01ed\u01ee\u0005e\u0000\u0000\u01ee"+
"\u01ef\u0005d\u0000\u0000\u01efD\u0001\u0000\u0000\u0000\u01f0\u01f1\u0005"+
"p\u0000\u0000\u01f1\u01f2\u0005u\u0000\u0000\u01f2\u01f3\u0005b\u0000"+
"\u0000\u01f3\u01f4\u0005l\u0000\u0000\u01f4\u01f5\u0005i\u0000\u0000\u01f5"+
"\u01f6\u0005c\u0000\u0000\u01f6F\u0001\u0000\u0000\u0000\u01f7\u01f8\u0005"+
"r\u0000\u0000\u01f8\u01f9\u0005e\u0000\u0000\u01f9\u01fa\u0005t\u0000"+
"\u0000\u01fa\u01fb\u0005u\u0000\u0000\u01fb\u01fc\u0005r\u0000\u0000\u01fc"+
"\u01fd\u0005n\u0000\u0000\u01fdH\u0001\u0000\u0000\u0000\u01fe\u01ff\u0005"+
"s\u0000\u0000\u01ff\u0200\u0005h\u0000\u0000\u0200\u0201\u0005o\u0000"+
"\u0000\u0201\u0202\u0005r\u0000\u0000\u0202\u0203\u0005t\u0000\u0000\u0203"+
"J\u0001\u0000\u0000\u0000\u0204\u0205\u0005s\u0000\u0000\u0205\u0206\u0005"+
"t\u0000\u0000\u0206\u0207\u0005a\u0000\u0000\u0207\u0208\u0005t\u0000"+
"\u0000\u0208\u0209\u0005i\u0000\u0000\u0209\u020a\u0005c\u0000\u0000\u020a"+
"L\u0001\u0000\u0000\u0000\u020b\u020c\u0005s\u0000\u0000\u020c\u020d\u0005"+
"t\u0000\u0000\u020d\u020e\u0005r\u0000\u0000\u020e\u020f\u0005i\u0000"+
"\u0000\u020f\u0210\u0005c\u0000\u0000\u0210\u0211\u0005t\u0000\u0000\u0211"+
"\u0212\u0005f\u0000\u0000\u0212\u0213\u0005p\u0000\u0000\u0213N\u0001"+
"\u0000\u0000\u0000\u0214\u0215\u0005s\u0000\u0000\u0215\u0216\u0005u\u0000"+
"\u0000\u0216\u0217\u0005p\u0000\u0000\u0217\u0218\u0005e\u0000\u0000\u0218"+
"\u0219\u0005r\u0000\u0000\u0219P\u0001\u0000\u0000\u0000\u021a\u021b\u0005"+
"s\u0000\u0000\u021b\u021c\u0005w\u0000\u0000\u021c\u021d\u0005i\u0000"+
"\u0000\u021d\u021e\u0005t\u0000\u0000\u021e\u021f\u0005c\u0000\u0000\u021f"+
"\u0220\u0005h\u0000\u0000\u0220R\u0001\u0000\u0000\u0000\u0221\u0222\u0005"+
"s\u0000\u0000\u0222\u0223\u0005y\u0000\u0000\u0223\u0224\u0005n\u0000"+
"\u0000\u0224\u0225\u0005c\u0000\u0000\u0225\u0226\u0005h\u0000\u0000\u0226"+
"\u0227\u0005r\u0000\u0000\u0227\u0228\u0005o\u0000\u0000\u0228\u0229\u0005"+
"n\u0000\u0000\u0229\u022a\u0005i\u0000\u0000\u022a\u022b\u0005z\u0000"+
"\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u022d\u0005d\u0000\u0000\u022d"+
"T\u0001\u0000\u0000\u0000\u022e\u022f\u0005t\u0000\u0000\u022f\u0230\u0005"+
"h\u0000\u0000\u0230\u0231\u0005i\u0000\u0000\u0231\u0232\u0005s\u0000"+
"\u0000\u0232V\u0001\u0000\u0000\u0000\u0233\u0234\u0005t\u0000\u0000\u0234"+
"\u0235\u0005h\u0000\u0000\u0235\u0236\u0005r\u0000\u0000\u0236\u0237\u0005"+
"o\u0000\u0000\u0237\u0238\u0005w\u0000\u0000\u0238X\u0001\u0000\u0000"+
"\u0000\u0239\u023a\u0005t\u0000\u0000\u023a\u023b\u0005h\u0000\u0000\u023b"+
"\u023c\u0005r\u0000\u0000\u023c\u023d\u0005o\u0000\u0000\u023d\u023e\u0005"+
"w\u0000\u0000\u023e\u023f\u0005s\u0000\u0000\u023fZ\u0001\u0000\u0000"+
"\u0000\u0240\u0241\u0005t\u0000\u0000\u0241\u0242\u0005r\u0000\u0000\u0242"+
"\u0243\u0005a\u0000\u0000\u0243\u0244\u0005n\u0000\u0000\u0244\u0245\u0005"+
"s\u0000\u0000\u0245\u0246\u0005i\u0000\u0000\u0246\u0247\u0005e\u0000"+
"\u0000\u0247\u0248\u0005n\u0000\u0000\u0248\u0249\u0005t\u0000\u0000\u0249"+
"\\\u0001\u0000\u0000\u0000\u024a\u024b\u0005t\u0000\u0000\u024b\u024c"+
"\u0005r\u0000\u0000\u024c\u024d\u0005y\u0000\u0000\u024d^\u0001\u0000"+
"\u0000\u0000\u024e\u024f\u0005v\u0000\u0000\u024f\u0250\u0005o\u0000\u0000"+
"\u0250\u0251\u0005i\u0000\u0000\u0251\u0252\u0005d\u0000\u0000\u0252`"+
"\u0001\u0000\u0000\u0000\u0253\u0254\u0005v\u0000\u0000\u0254\u0255\u0005"+
"o\u0000\u0000\u0255\u0256\u0005l\u0000\u0000\u0256\u0257\u0005a\u0000"+
"\u0000\u0257\u0258\u0005t\u0000\u0000\u0258\u0259\u0005i\u0000\u0000\u0259"+
"\u025a\u0005l\u0000\u0000\u025a\u025b\u0005e\u0000\u0000\u025bb\u0001"+
"\u0000\u0000\u0000\u025c\u025d\u0005w\u0000\u0000\u025d\u025e\u0005h\u0000"+
"\u0000\u025e\u025f\u0005i\u0000\u0000\u025f\u0260\u0005l\u0000\u0000\u0260"+
"\u0261\u0005e\u0000\u0000\u0261d\u0001\u0000\u0000\u0000\u0262\u0263\u0005"+
"m\u0000\u0000\u0263\u0264\u0005o\u0000\u0000\u0264\u0265\u0005d\u0000"+
"\u0000\u0265\u0266\u0005u\u0000\u0000\u0266\u0267\u0005l\u0000\u0000\u0267"+
"\u0268\u0005e\u0000\u0000\u0268f\u0001\u0000\u0000\u0000\u0269\u026a\u0005"+
"o\u0000\u0000\u026a\u026b\u0005p\u0000\u0000\u026b\u026c\u0005e\u0000"+
"\u0000\u026c\u026d\u0005n\u0000\u0000\u026dh\u0001\u0000\u0000\u0000\u026e"+
"\u026f\u0005r\u0000\u0000\u026f\u0270\u0005e\u0000\u0000\u0270\u0271\u0005"+
"q\u0000\u0000\u0271\u0272\u0005u\u0000\u0000\u0272\u0273\u0005i\u0000"+
"\u0000\u0273\u0274\u0005r\u0000\u0000\u0274\u0275\u0005e\u0000\u0000\u0275"+
"\u0276\u0005s\u0000\u0000\u0276j\u0001\u0000\u0000\u0000\u0277\u0278\u0005"+
"e\u0000\u0000\u0278\u0279\u0005x\u0000\u0000\u0279\u027a\u0005p\u0000"+
"\u0000\u027a\u027b\u0005o\u0000\u0000\u027b\u027c\u0005r\u0000\u0000\u027c"+
"\u027d\u0005t\u0000\u0000\u027d\u027e\u0005s\u0000\u0000\u027el\u0001"+
"\u0000\u0000\u0000\u027f\u0280\u0005o\u0000\u0000\u0280\u0281\u0005p\u0000"+
"\u0000\u0281\u0282\u0005e\u0000\u0000\u0282\u0283\u0005n\u0000\u0000\u0283"+
"\u0284\u0005s\u0000\u0000\u0284n\u0001\u0000\u0000\u0000\u0285\u0286\u0005"+
"t\u0000\u0000\u0286\u0287\u0005o\u0000\u0000\u0287p\u0001\u0000\u0000"+
"\u0000\u0288\u0289\u0005u\u0000\u0000\u0289\u028a\u0005s\u0000\u0000\u028a"+
"\u028b\u0005e\u0000\u0000\u028b\u028c\u0005s\u0000\u0000\u028cr\u0001"+
"\u0000\u0000\u0000\u028d\u028e\u0005p\u0000\u0000\u028e\u028f\u0005r\u0000"+
"\u0000\u028f\u0290\u0005o\u0000\u0000\u0290\u0291\u0005v\u0000\u0000\u0291"+
"\u0292\u0005i\u0000\u0000\u0292\u0293\u0005d\u0000\u0000\u0293\u0294\u0005"+
"e\u0000\u0000\u0294\u0295\u0005s\u0000\u0000\u0295t\u0001\u0000\u0000"+
"\u0000\u0296\u0297\u0005w\u0000\u0000\u0297\u0298\u0005i\u0000\u0000\u0298"+
"\u0299\u0005t\u0000\u0000\u0299\u029a\u0005h\u0000\u0000\u029av\u0001"+
"\u0000\u0000\u0000\u029b\u029c\u0005t\u0000\u0000\u029c\u029d\u0005r\u0000"+
"\u0000\u029d\u029e\u0005a\u0000\u0000\u029e\u029f\u0005n\u0000\u0000\u029f"+
"\u02a0\u0005s\u0000\u0000\u02a0\u02a1\u0005i\u0000\u0000\u02a1\u02a2\u0005"+
"t\u0000\u0000\u02a2\u02a3\u0005i\u0000\u0000\u02a3\u02a4\u0005v\u0000"+
"\u0000\u02a4\u02a5\u0005e\u0000\u0000\u02a5x\u0001\u0000\u0000\u0000\u02a6"+
"\u02a7\u0005v\u0000\u0000\u02a7\u02a8\u0005a\u0000\u0000\u02a8\u02a9\u0005"+
"r\u0000\u0000\u02a9z\u0001\u0000\u0000\u0000\u02aa\u02ab\u0005y\u0000"+
"\u0000\u02ab\u02ac\u0005i\u0000\u0000\u02ac\u02ad\u0005e\u0000\u0000\u02ad"+
"\u02ae\u0005l\u0000\u0000\u02ae\u02af\u0005d\u0000\u0000\u02af|\u0001"+
"\u0000\u0000\u0000\u02b0\u02b1\u0005r\u0000\u0000\u02b1\u02b2\u0005e\u0000"+
"\u0000\u02b2\u02b3\u0005c\u0000\u0000\u02b3\u02b4\u0005o\u0000\u0000\u02b4"+
"\u02b5\u0005r\u0000\u0000\u02b5\u02b6\u0005d\u0000\u0000\u02b6~\u0001"+
"\u0000\u0000\u0000\u02b7\u02b8\u0005s\u0000\u0000\u02b8\u02b9\u0005e\u0000"+
"\u0000\u02b9\u02ba\u0005a\u0000\u0000\u02ba\u02bb\u0005l\u0000\u0000\u02bb"+
"\u02bc\u0005e\u0000\u0000\u02bc\u02bd\u0005d\u0000\u0000\u02bd\u0080\u0001"+
"\u0000\u0000\u0000\u02be\u02bf\u0005p\u0000\u0000\u02bf\u02c0\u0005e\u0000"+
"\u0000\u02c0\u02c1\u0005r\u0000\u0000\u02c1\u02c2\u0005m\u0000\u0000\u02c2"+
"\u02c3\u0005i\u0000\u0000\u02c3\u02c4\u0005t\u0000\u0000\u02c4\u02c5\u0005"+
"s\u0000\u0000\u02c5\u0082\u0001\u0000\u0000\u0000\u02c6\u02c7\u0005n\u0000"+
"\u0000\u02c7\u02c8\u0005o\u0000\u0000\u02c8\u02c9\u0005n\u0000\u0000\u02c9"+
"\u02ca\u0005-\u0000\u0000\u02ca\u02cb\u0005s\u0000\u0000\u02cb\u02cc\u0005"+
"e\u0000\u0000\u02cc\u02cd\u0005a\u0000\u0000\u02cd\u02ce\u0005l\u0000"+
"\u0000\u02ce\u02cf\u0005e\u0000\u0000\u02cf\u02d0\u0005d\u0000\u0000\u02d0"+
"\u0084\u0001\u0000\u0000\u0000\u02d1\u02df\u00050\u0000\u0000\u02d2\u02dc"+
"\u0007\u0000\u0000\u0000\u02d3\u02d5\u0003\u0109\u0084\u0000\u02d4\u02d3"+
"\u0001\u0000\u0000\u0000\u02d4\u02d5\u0001\u0000\u0000\u0000\u02d5\u02dd"+
"\u0001\u0000\u0000\u0000\u02d6\u02d8\u0005_\u0000\u0000\u02d7\u02d6\u0001"+
"\u0000\u0000\u0000\u02d8\u02d9\u0001\u0000\u0000\u0000\u02d9\u02d7\u0001"+
"\u0000\u0000\u0000\u02d9\u02da\u0001\u0000\u0000\u0000\u02da\u02db\u0001"+
"\u0000\u0000\u0000\u02db\u02dd\u0003\u0109\u0084\u0000\u02dc\u02d4\u0001"+
"\u0000\u0000\u0000\u02dc\u02d7\u0001\u0000\u0000\u0000\u02dd\u02df\u0001"+
"\u0000\u0000\u0000\u02de\u02d1\u0001\u0000\u0000\u0000\u02de\u02d2\u0001"+
"\u0000\u0000\u0000\u02df\u02e1\u0001\u0000\u0000\u0000\u02e0\u02e2\u0007"+
"\u0001\u0000\u0000\u02e1\u02e0\u0001\u0000\u0000\u0000\u02e1\u02e2\u0001"+
"\u0000\u0000\u0000\u02e2\u0086\u0001\u0000\u0000\u0000\u02e3\u02e4\u0005"+
"0\u0000\u0000\u02e4\u02e5\u0007\u0002\u0000\u0000\u02e5\u02ed\u0007\u0003"+
"\u0000\u0000\u02e6\u02e8\u0007\u0004\u0000\u0000\u02e7\u02e6\u0001\u0000"+
"\u0000\u0000\u02e8\u02eb\u0001\u0000\u0000\u0000\u02e9\u02e7\u0001\u0000"+
"\u0000\u0000\u02e9\u02ea\u0001\u0000\u0000\u0000\u02ea\u02ec\u0001\u0000"+
"\u0000\u0000\u02eb\u02e9\u0001\u0000\u0000\u0000\u02ec\u02ee\u0007\u0003"+
"\u0000\u0000\u02ed\u02e9\u0001\u0000\u0000\u0000\u02ed\u02ee\u0001\u0000"+
"\u0000\u0000\u02ee\u02f0\u0001\u0000\u0000\u0000\u02ef\u02f1\u0007\u0001"+
"\u0000\u0000\u02f0\u02ef\u0001\u0000\u0000\u0000\u02f0\u02f1\u0001\u0000"+
"\u0000\u0000\u02f1\u0088\u0001\u0000\u0000\u0000\u02f2\u02f6\u00050\u0000"+
"\u0000\u02f3\u02f5\u0005_\u0000\u0000\u02f4\u02f3\u0001\u0000\u0000\u0000"+
"\u02f5\u02f8\u0001\u0000\u0000\u0000\u02f6\u02f4\u0001\u0000\u0000\u0000"+
"\u02f6\u02f7\u0001\u0000\u0000\u0000\u02f7\u02f9\u0001\u0000\u0000\u0000"+
"\u02f8\u02f6\u0001\u0000\u0000\u0000\u02f9\u0301\u0007\u0005\u0000\u0000"+
"\u02fa\u02fc\u0007\u0006\u0000\u0000\u02fb\u02fa\u0001\u0000\u0000\u0000"+
"\u02fc\u02ff\u0001\u0000\u0000\u0000\u02fd\u02fb\u0001\u0000\u0000\u0000"+
"\u02fd\u02fe\u0001\u0000\u0000\u0000\u02fe\u0300\u0001\u0000\u0000\u0000"+
"\u02ff\u02fd\u0001\u0000\u0000\u0000\u0300\u0302\u0007\u0005\u0000\u0000"+
"\u0301\u02fd\u0001\u0000\u0000\u0000\u0301\u0302\u0001\u0000\u0000\u0000"+
"\u0302\u0304\u0001\u0000\u0000\u0000\u0303\u0305\u0007\u0001\u0000\u0000"+
"\u0304\u0303\u0001\u0000\u0000\u0000\u0304\u0305\u0001\u0000\u0000\u0000"+
"\u0305\u008a\u0001\u0000\u0000\u0000\u0306\u0307\u00050\u0000\u0000\u0307"+
"\u0308\u0007\u0007\u0000\u0000\u0308\u0310\u0007\b\u0000\u0000\u0309\u030b"+
"\u0007\t\u0000\u0000\u030a\u0309\u0001\u0000\u0000\u0000\u030b\u030e\u0001"+
"\u0000\u0000\u0000\u030c\u030a\u0001\u0000\u0000\u0000\u030c\u030d\u0001"+
"\u0000\u0000\u0000\u030d\u030f\u0001\u0000\u0000\u0000\u030e\u030c\u0001"+
"\u0000\u0000\u0000\u030f\u0311\u0007\b\u0000\u0000\u0310\u030c\u0001\u0000"+
"\u0000\u0000\u0310\u0311\u0001\u0000\u0000\u0000\u0311\u0313\u0001\u0000"+
"\u0000\u0000\u0312\u0314\u0007\u0001\u0000\u0000\u0313\u0312\u0001\u0000"+
"\u0000\u0000\u0313\u0314\u0001\u0000\u0000\u0000\u0314\u008c\u0001\u0000"+
"\u0000\u0000\u0315\u0316\u0003\u0109\u0084\u0000\u0316\u0318\u0005.\u0000"+
"\u0000\u0317\u0319\u0003\u0109\u0084\u0000\u0318\u0317\u0001\u0000\u0000"+
"\u0000\u0318\u0319\u0001\u0000\u0000\u0000\u0319\u031d\u0001\u0000\u0000"+
"\u0000\u031a\u031b\u0005.\u0000\u0000\u031b\u031d\u0003\u0109\u0084\u0000"+
"\u031c\u0315\u0001\u0000\u0000\u0000\u031c\u031a\u0001\u0000\u0000\u0000"+
"\u031d\u031f\u0001\u0000\u0000\u0000\u031e\u0320\u0003\u0101\u0080\u0000"+
"\u031f\u031e\u0001\u0000\u0000\u0000\u031f\u0320\u0001\u0000\u0000\u0000"+
"\u0320\u0322\u0001\u0000\u0000\u0000\u0321\u0323\u0007\n\u0000\u0000\u0322"+
"\u0321\u0001\u0000\u0000\u0000\u0322\u0323\u0001\u0000\u0000\u0000\u0323"+
"\u032d\u0001\u0000\u0000\u0000\u0324\u032a\u0003\u0109\u0084\u0000\u0325"+
"\u0327\u0003\u0101\u0080\u0000\u0326\u0328\u0007\n\u0000\u0000\u0327\u0326"+
"\u0001\u0000\u0000\u0000\u0327\u0328\u0001\u0000\u0000\u0000\u0328\u032b"+
"\u0001\u0000\u0000\u0000\u0329\u032b\u0007\n\u0000\u0000\u032a\u0325\u0001"+
"\u0000\u0000\u0000\u032a\u0329\u0001\u0000\u0000\u0000\u032b\u032d\u0001"+
"\u0000\u0000\u0000\u032c\u031c\u0001\u0000\u0000\u0000\u032c\u0324\u0001"+
"\u0000\u0000\u0000\u032d\u008e\u0001\u0000\u0000\u0000\u032e\u032f\u0005"+
"0\u0000\u0000\u032f\u0339\u0007\u0002\u0000\u0000\u0330\u0332\u0003\u0105"+
"\u0082\u0000\u0331\u0333\u0005.\u0000\u0000\u0332\u0331\u0001\u0000\u0000"+
"\u0000\u0332\u0333\u0001\u0000\u0000\u0000\u0333\u033a\u0001\u0000\u0000"+
"\u0000\u0334\u0336\u0003\u0105\u0082\u0000\u0335\u0334\u0001\u0000\u0000"+
"\u0000\u0335\u0336\u0001\u0000\u0000\u0000\u0336\u0337\u0001\u0000\u0000"+
"\u0000\u0337\u0338\u0005.\u0000\u0000\u0338\u033a\u0003\u0105\u0082\u0000"+
"\u0339\u0330\u0001\u0000\u0000\u0000\u0339\u0335\u0001\u0000\u0000\u0000"+
"\u033a\u033b\u0001\u0000\u0000\u0000\u033b\u033d\u0007\u000b\u0000\u0000"+
"\u033c\u033e\u0007\f\u0000\u0000\u033d\u033c\u0001\u0000\u0000\u0000\u033d"+
"\u033e\u0001\u0000\u0000\u0000\u033e\u033f\u0001\u0000\u0000\u0000\u033f"+
"\u0341\u0003\u0109\u0084\u0000\u0340\u0342\u0007\n\u0000\u0000\u0341\u0340"+
"\u0001\u0000\u0000\u0000\u0341\u0342\u0001\u0000\u0000\u0000\u0342\u0090"+
"\u0001\u0000\u0000\u0000\u0343\u0344\u0005t\u0000\u0000\u0344\u0345\u0005"+
"r\u0000\u0000\u0345\u0346\u0005u\u0000\u0000\u0346\u034d\u0005e\u0000"+
"\u0000\u0347\u0348\u0005f\u0000\u0000\u0348\u0349\u0005a\u0000\u0000\u0349"+
"\u034a\u0005l\u0000\u0000\u034a\u034b\u0005s\u0000\u0000\u034b\u034d\u0005"+
"e\u0000\u0000\u034c\u0343\u0001\u0000\u0000\u0000\u034c\u0347\u0001\u0000"+
"\u0000\u0000\u034d\u0092\u0001\u0000\u0000\u0000\u034e\u0351\u0005\'\u0000"+
"\u0000\u034f\u0352\b\r\u0000\u0000\u0350\u0352\u0003\u0103\u0081\u0000"+
"\u0351\u034f\u0001\u0000\u0000\u0000\u0351\u0350\u0001\u0000\u0000\u0000"+
"\u0352\u0353\u0001\u0000\u0000\u0000\u0353\u0354\u0005\'\u0000\u0000\u0354"+
"\u0094\u0001\u0000\u0000\u0000\u0355\u035a\u0005\"\u0000\u0000\u0356\u0359"+
"\b\u000e\u0000\u0000\u0357\u0359\u0003\u0103\u0081\u0000\u0358\u0356\u0001"+
"\u0000\u0000\u0000\u0358\u0357\u0001\u0000\u0000\u0000\u0359\u035c\u0001"+
"\u0000\u0000\u0000\u035a\u0358\u0001\u0000\u0000\u0000\u035a\u035b\u0001"+
"\u0000\u0000\u0000\u035b\u035d\u0001\u0000\u0000\u0000\u035c\u035a\u0001"+
"\u0000\u0000\u0000\u035d\u035e\u0005\"\u0000\u0000\u035e\u0096\u0001\u0000"+
"\u0000\u0000\u035f\u0360\u0005\"\u0000\u0000\u0360\u0361\u0005\"\u0000"+
"\u0000\u0361\u0362\u0005\"\u0000\u0000\u0362\u0366\u0001\u0000\u0000\u0000"+
"\u0363\u0365\u0007\u000f\u0000\u0000\u0364\u0363\u0001\u0000\u0000\u0000"+
"\u0365\u0368\u0001\u0000\u0000\u0000\u0366\u0364\u0001\u0000\u0000\u0000"+
"\u0366\u0367\u0001\u0000\u0000\u0000\u0367\u0369\u0001\u0000\u0000\u0000"+
"\u0368\u0366\u0001\u0000\u0000\u0000\u0369\u036e\u0007\u0010\u0000\u0000"+
"\u036a\u036d\t\u0000\u0000\u0000\u036b\u036d\u0003\u0103\u0081\u0000\u036c"+
"\u036a\u0001\u0000\u0000\u0000\u036c\u036b\u0001\u0000\u0000\u0000\u036d"+
"\u0370\u0001\u0000\u0000\u0000\u036e\u036f\u0001\u0000\u0000\u0000\u036e"+
"\u036c\u0001\u0000\u0000\u0000\u036f\u0371\u0001\u0000\u0000\u0000\u0370"+
"\u036e\u0001\u0000\u0000\u0000\u0371\u0372\u0005\"\u0000\u0000\u0372\u0373"+
"\u0005\"\u0000\u0000\u0373\u0374\u0005\"\u0000\u0000\u0374\u0098\u0001"+
"\u0000\u0000\u0000\u0375\u0376\u0005n\u0000\u0000\u0376\u0377\u0005u\u0000"+
"\u0000\u0377\u0378\u0005l\u0000\u0000\u0378\u0379\u0005l\u0000\u0000\u0379"+
"\u009a\u0001\u0000\u0000\u0000\u037a\u037b\u0005(\u0000\u0000\u037b\u009c"+
"\u0001\u0000\u0000\u0000\u037c\u037d\u0005)\u0000\u0000\u037d\u009e\u0001"+
"\u0000\u0000\u0000\u037e\u037f\u0005{\u0000\u0000\u037f\u00a0\u0001\u0000"+
"\u0000\u0000\u0380\u0381\u0005}\u0000\u0000\u0381\u00a2\u0001\u0000\u0000"+
"\u0000\u0382\u0383\u0005[\u0000\u0000\u0383\u00a4\u0001\u0000\u0000\u0000"+
"\u0384\u0385\u0005]\u0000\u0000\u0385\u00a6\u0001\u0000\u0000\u0000\u0386"+
"\u0387\u0005;\u0000\u0000\u0387\u00a8\u0001\u0000\u0000\u0000\u0388\u0389"+
"\u0005,\u0000\u0000\u0389\u00aa\u0001\u0000\u0000\u0000\u038a\u038b\u0005"+
".\u0000\u0000\u038b\u00ac\u0001\u0000\u0000\u0000\u038c\u038d\u0005=\u0000"+
"\u0000\u038d\u00ae\u0001\u0000\u0000\u0000\u038e\u038f\u0005>\u0000\u0000"+
"\u038f\u00b0\u0001\u0000\u0000\u0000\u0390\u0391\u0005<\u0000\u0000\u0391"+
"\u00b2\u0001\u0000\u0000\u0000\u0392\u0393\u0005!\u0000\u0000\u0393\u00b4"+
"\u0001\u0000\u0000\u0000\u0394\u0395\u0005~\u0000\u0000\u0395\u00b6\u0001"+
"\u0000\u0000\u0000\u0396\u0397\u0005?\u0000\u0000\u0397\u00b8\u0001\u0000"+
"\u0000\u0000\u0398\u0399\u0005:\u0000\u0000\u0399\u00ba\u0001\u0000\u0000"+
"\u0000\u039a\u039b\u0005=\u0000\u0000\u039b\u039c\u0005=\u0000\u0000\u039c"+
"\u00bc\u0001\u0000\u0000\u0000\u039d\u039e\u0005<\u0000\u0000\u039e\u039f"+
"\u0005=\u0000\u0000\u039f\u00be\u0001\u0000\u0000\u0000\u03a0\u03a1\u0005"+
">\u0000\u0000\u03a1\u03a2\u0005=\u0000\u0000\u03a2\u00c0\u0001\u0000\u0000"+
"\u0000\u03a3\u03a4\u0005!\u0000\u0000\u03a4\u03a5\u0005=\u0000\u0000\u03a5"+
"\u00c2\u0001\u0000\u0000\u0000\u03a6\u03a7\u0005&\u0000\u0000\u03a7\u03a8"+
"\u0005&\u0000\u0000\u03a8\u00c4\u0001\u0000\u0000\u0000\u03a9\u03aa\u0005"+
"|\u0000\u0000\u03aa\u03ab\u0005|\u0000\u0000\u03ab\u00c6\u0001\u0000\u0000"+
"\u0000\u03ac\u03ad\u0005+\u0000\u0000\u03ad\u03ae\u0005+\u0000\u0000\u03ae"+
"\u00c8\u0001\u0000\u0000\u0000\u03af\u03b0\u0005-\u0000\u0000\u03b0\u03b1"+
"\u0005-\u0000\u0000\u03b1\u00ca\u0001\u0000\u0000\u0000\u03b2\u03b3\u0005"+
"+\u0000\u0000\u03b3\u00cc\u0001\u0000\u0000\u0000\u03b4\u03b5\u0005-\u0000"+
"\u0000\u03b5\u00ce\u0001\u0000\u0000\u0000\u03b6\u03b7\u0005*\u0000\u0000"+
"\u03b7\u00d0\u0001\u0000\u0000\u0000\u03b8\u03b9\u0005/\u0000\u0000\u03b9"+
"\u00d2\u0001\u0000\u0000\u0000\u03ba\u03bb\u0005&\u0000\u0000\u03bb\u00d4"+
"\u0001\u0000\u0000\u0000\u03bc\u03bd\u0005|\u0000\u0000\u03bd\u00d6\u0001"+
"\u0000\u0000\u0000\u03be\u03bf\u0005^\u0000\u0000\u03bf\u00d8\u0001\u0000"+
"\u0000\u0000\u03c0\u03c1\u0005%\u0000\u0000\u03c1\u00da\u0001\u0000\u0000"+
"\u0000\u03c2\u03c3\u0005+\u0000\u0000\u03c3\u03c4\u0005=\u0000\u0000\u03c4"+
"\u00dc\u0001\u0000\u0000\u0000\u03c5\u03c6\u0005-\u0000\u0000\u03c6\u03c7"+
"\u0005=\u0000\u0000\u03c7\u00de\u0001\u0000\u0000\u0000\u03c8\u03c9\u0005"+
"*\u0000\u0000\u03c9\u03ca\u0005=\u0000\u0000\u03ca\u00e0\u0001\u0000\u0000"+
"\u0000\u03cb\u03cc\u0005/\u0000\u0000\u03cc\u03cd\u0005=\u0000\u0000\u03cd"+
"\u00e2\u0001\u0000\u0000\u0000\u03ce\u03cf\u0005&\u0000\u0000\u03cf\u03d0"+
"\u0005=\u0000\u0000\u03d0\u00e4\u0001\u0000\u0000\u0000\u03d1\u03d2\u0005"+
"|\u0000\u0000\u03d2\u03d3\u0005=\u0000\u0000\u03d3\u00e6\u0001\u0000\u0000"+
"\u0000\u03d4\u03d5\u0005^\u0000\u0000\u03d5\u03d6\u0005=\u0000\u0000\u03d6"+
"\u00e8\u0001\u0000\u0000\u0000\u03d7\u03d8\u0005%\u0000\u0000\u03d8\u03d9"+
"\u0005=\u0000\u0000\u03d9\u00ea\u0001\u0000\u0000\u0000\u03da\u03db\u0005"+
"<\u0000\u0000\u03db\u03dc\u0005<\u0000\u0000\u03dc\u03dd\u0005=\u0000"+
"\u0000\u03dd\u00ec\u0001\u0000\u0000\u0000\u03de\u03df\u0005>\u0000\u0000"+
"\u03df\u03e0\u0005>\u0000\u0000\u03e0\u03e1\u0005=\u0000\u0000\u03e1\u00ee"+
"\u0001\u0000\u0000\u0000\u03e2\u03e3\u0005>\u0000\u0000\u03e3\u03e4\u0005"+
">\u0000\u0000\u03e4\u03e5\u0005>\u0000\u0000\u03e5\u03e6\u0005=\u0000"+
"\u0000\u03e6\u00f0\u0001\u0000\u0000\u0000\u03e7\u03e8\u0005-\u0000\u0000"+
"\u03e8\u03e9\u0005>\u0000\u0000\u03e9\u00f2\u0001\u0000\u0000\u0000\u03ea"+
"\u03eb\u0005:\u0000\u0000\u03eb\u03ec\u0005:\u0000\u0000\u03ec\u00f4\u0001"+
"\u0000\u0000\u0000\u03ed\u03ee\u0005@\u0000\u0000\u03ee\u00f6\u0001\u0000"+
"\u0000\u0000\u03ef\u03f0\u0005.\u0000\u0000\u03f0\u03f1\u0005.\u0000\u0000"+
"\u03f1\u03f2\u0005.\u0000\u0000\u03f2\u00f8\u0001\u0000\u0000\u0000\u03f3"+
"\u03f5\u0007\u0011\u0000\u0000\u03f4\u03f3\u0001\u0000\u0000\u0000\u03f5"+
"\u03f6\u0001\u0000\u0000\u0000\u03f6\u03f4\u0001\u0000\u0000\u0000\u03f6"+
"\u03f7\u0001\u0000\u0000\u0000\u03f7\u03f8\u0001\u0000\u0000\u0000\u03f8"+
"\u03f9\u0006|\u0000\u0000\u03f9\u00fa\u0001\u0000\u0000\u0000\u03fa\u03fb"+
"\u0005/\u0000\u0000\u03fb\u03fc\u0005*\u0000\u0000\u03fc\u0400\u0001\u0000"+
"\u0000\u0000\u03fd\u03ff\t\u0000\u0000\u0000\u03fe\u03fd\u0001\u0000\u0000"+
"\u0000\u03ff\u0402\u0001\u0000\u0000\u0000\u0400\u0401\u0001\u0000\u0000"+
"\u0000\u0400\u03fe\u0001\u0000\u0000\u0000\u0401\u0403\u0001\u0000\u0000"+
"\u0000\u0402\u0400\u0001\u0000\u0000\u0000\u0403\u0404\u0005*\u0000\u0000"+
"\u0404\u0405\u0005/\u0000\u0000\u0405\u0406\u0001\u0000\u0000\u0000\u0406"+
"\u0407\u0006}\u0000\u0000\u0407\u00fc\u0001\u0000\u0000\u0000\u0408\u0409"+
"\u0005/\u0000\u0000\u0409\u040a\u0005/\u0000\u0000\u040a\u040e\u0001\u0000"+
"\u0000\u0000\u040b\u040d\b\u0010\u0000\u0000\u040c\u040b\u0001\u0000\u0000"+
"\u0000\u040d\u0410\u0001\u0000\u0000\u0000\u040e\u040c\u0001\u0000\u0000"+
"\u0000\u040e\u040f\u0001\u0000\u0000\u0000\u040f\u0411\u0001\u0000\u0000"+
"\u0000\u0410\u040e\u0001\u0000\u0000\u0000\u0411\u0412\u0006~\u0000\u0000"+
"\u0412\u00fe\u0001\u0000\u0000\u0000\u0413\u0417\u0003\u010d\u0086\u0000"+
"\u0414\u0416\u0003\u010b\u0085\u0000\u0415\u0414\u0001\u0000\u0000\u0000"+
"\u0416\u0419\u0001\u0000\u0000\u0000\u0417\u0415\u0001\u0000\u0000\u0000"+
"\u0417\u0418\u0001\u0000\u0000\u0000\u0418\u0100\u0001\u0000\u0000\u0000"+
"\u0419\u0417\u0001\u0000\u0000\u0000\u041a\u041c\u0007\u0012\u0000\u0000"+
"\u041b\u041d\u0007\f\u0000\u0000\u041c\u041b\u0001\u0000\u0000\u0000\u041c"+
"\u041d\u0001\u0000\u0000\u0000\u041d\u041e\u0001\u0000\u0000\u0000\u041e"+
"\u041f\u0003\u0109\u0084\u0000\u041f\u0102\u0001\u0000\u0000\u0000\u0420"+
"\u0421\u0005\\\u0000\u0000\u0421\u0436\u0007\u0013\u0000\u0000\u0422\u0427"+
"\u0005\\\u0000\u0000\u0423\u0425\u0007\u0014\u0000\u0000\u0424\u0423\u0001"+
"\u0000\u0000\u0000\u0424\u0425\u0001\u0000\u0000\u0000\u0425\u0426\u0001"+
"\u0000\u0000\u0000\u0426\u0428\u0007\u0005\u0000\u0000\u0427\u0424\u0001"+
"\u0000\u0000\u0000\u0427\u0428\u0001\u0000\u0000\u0000\u0428\u0429\u0001"+
"\u0000\u0000\u0000\u0429\u0436\u0007\u0005\u0000\u0000\u042a\u042c\u0005"+
"\\\u0000\u0000\u042b\u042d\u0005u\u0000\u0000\u042c\u042b\u0001\u0000"+
"\u0000\u0000\u042d\u042e\u0001\u0000\u0000\u0000\u042e\u042c\u0001\u0000"+
"\u0000\u0000\u042e\u042f\u0001\u0000\u0000\u0000\u042f\u0430\u0001\u0000"+
"\u0000\u0000\u0430\u0431\u0003\u0107\u0083\u0000\u0431\u0432\u0003\u0107"+
"\u0083\u0000\u0432\u0433\u0003\u0107\u0083\u0000\u0433\u0434\u0003\u0107"+
"\u0083\u0000\u0434\u0436\u0001\u0000\u0000\u0000\u0435\u0420\u0001\u0000"+
"\u0000\u0000\u0435\u0422\u0001\u0000\u0000\u0000\u0435\u042a\u0001\u0000"+
"\u0000\u0000\u0436\u0104\u0001\u0000\u0000\u0000\u0437\u0440\u0003\u0107"+
"\u0083\u0000\u0438\u043b\u0003\u0107\u0083\u0000\u0439\u043b\u0005_\u0000"+
"\u0000\u043a\u0438\u0001\u0000\u0000\u0000\u043a\u0439\u0001\u0000\u0000"+
"\u0000\u043b\u043e\u0001\u0000\u0000\u0000\u043c\u043a\u0001\u0000\u0000"+
"\u0000\u043c\u043d\u0001\u0000\u0000\u0000\u043d\u043f\u0001\u0000\u0000"+
"\u0000\u043e\u043c\u0001\u0000\u0000\u0000\u043f\u0441\u0003\u0107\u0083"+
"\u0000\u0440\u043c\u0001\u0000\u0000\u0000\u0440\u0441\u0001\u0000\u0000"+
"\u0000\u0441\u0106\u0001\u0000\u0000\u0000\u0442\u0443\u0007\u0003\u0000"+
"\u0000\u0443\u0108\u0001\u0000\u0000\u0000\u0444\u044c\u0007\u0015\u0000"+
"\u0000\u0445\u0447\u0007\u0016\u0000\u0000\u0446\u0445\u0001\u0000\u0000"+
"\u0000\u0447\u044a\u0001\u0000\u0000\u0000\u0448\u0446\u0001\u0000\u0000"+
"\u0000\u0448\u0449\u0001\u0000\u0000\u0000\u0449\u044b\u0001\u0000\u0000"+
"\u0000\u044a\u0448\u0001\u0000\u0000\u0000\u044b\u044d\u0007\u0015\u0000"+
"\u0000\u044c\u0448\u0001\u0000\u0000\u0000\u044c\u044d\u0001\u0000\u0000"+
"\u0000\u044d\u010a\u0001\u0000\u0000\u0000\u044e\u0451\u0003\u010d\u0086"+
"\u0000\u044f\u0451\u0007\u0015\u0000\u0000\u0450\u044e\u0001\u0000\u0000"+
"\u0000\u0450\u044f\u0001\u0000\u0000\u0000\u0451\u010c\u0001\u0000\u0000"+
"\u0000\u0452\u0457\u0007\u0017\u0000\u0000\u0453\u0457\b\u0018\u0000\u0000"+
"\u0454\u0455\u0007\u0019\u0000\u0000\u0455\u0457\u0007\u001a\u0000\u0000"+
"\u0456\u0452\u0001\u0000\u0000\u0000\u0456\u0453\u0001\u0000\u0000\u0000"+
"\u0456\u0454\u0001\u0000\u0000\u0000\u0457\u010e\u0001\u0000\u0000\u0000"+
"3\u0000\u02d4\u02d9\u02dc\u02de\u02e1\u02e9\u02ed\u02f0\u02f6\u02fd\u0301"+
"\u0304\u030c\u0310\u0313\u0318\u031c\u031f\u0322\u0327\u032a\u032c\u0332"+
"\u0335\u0339\u033d\u0341\u034c\u0351\u0358\u035a\u0366\u036c\u036e\u03f6"+
"\u0400\u040e\u0417\u041c\u0424\u0427\u042e\u0435\u043a\u043c\u0440\u0448"+
"\u044c\u0450\u0456\u0001\u0000\u0001\u0000";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}
+242
View File
@@ -0,0 +1,242 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124
File diff suppressed because one or more lines are too long
+15685
View File
File diff suppressed because it is too large Load Diff
+242
View File
@@ -0,0 +1,242 @@
ABSTRACT=1
ASSERT=2
BOOLEAN=3
BREAK=4
BYTE=5
CASE=6
CATCH=7
CHAR=8
CLASS=9
CONST=10
CONTINUE=11
DEFAULT=12
DO=13
DOUBLE=14
ELSE=15
ENUM=16
EXTENDS=17
FINAL=18
FINALLY=19
FLOAT=20
FOR=21
IF=22
GOTO=23
IMPLEMENTS=24
IMPORT=25
INSTANCEOF=26
INT=27
INTERFACE=28
LONG=29
NATIVE=30
NEW=31
PACKAGE=32
PRIVATE=33
PROTECTED=34
PUBLIC=35
RETURN=36
SHORT=37
STATIC=38
STRICTFP=39
SUPER=40
SWITCH=41
SYNCHRONIZED=42
THIS=43
THROW=44
THROWS=45
TRANSIENT=46
TRY=47
VOID=48
VOLATILE=49
WHILE=50
MODULE=51
OPEN=52
REQUIRES=53
EXPORTS=54
OPENS=55
TO=56
USES=57
PROVIDES=58
WITH=59
TRANSITIVE=60
VAR=61
YIELD=62
RECORD=63
SEALED=64
PERMITS=65
NON_SEALED=66
DECIMAL_LITERAL=67
HEX_LITERAL=68
OCT_LITERAL=69
BINARY_LITERAL=70
FLOAT_LITERAL=71
HEX_FLOAT_LITERAL=72
BOOL_LITERAL=73
CHAR_LITERAL=74
STRING_LITERAL=75
TEXT_BLOCK=76
NULL_LITERAL=77
LPAREN=78
RPAREN=79
LBRACE=80
RBRACE=81
LBRACK=82
RBRACK=83
SEMI=84
COMMA=85
DOT=86
ASSIGN=87
GT=88
LT=89
BANG=90
TILDE=91
QUESTION=92
COLON=93
EQUAL=94
LE=95
GE=96
NOTEQUAL=97
AND=98
OR=99
INC=100
DEC=101
ADD=102
SUB=103
MUL=104
DIV=105
BITAND=106
BITOR=107
CARET=108
MOD=109
ADD_ASSIGN=110
SUB_ASSIGN=111
MUL_ASSIGN=112
DIV_ASSIGN=113
AND_ASSIGN=114
OR_ASSIGN=115
XOR_ASSIGN=116
MOD_ASSIGN=117
LSHIFT_ASSIGN=118
RSHIFT_ASSIGN=119
URSHIFT_ASSIGN=120
ARROW=121
COLONCOLON=122
AT=123
ELLIPSIS=124
WS=125
COMMENT=126
LINE_COMMENT=127
IDENTIFIER=128
'abstract'=1
'assert'=2
'boolean'=3
'break'=4
'byte'=5
'case'=6
'catch'=7
'char'=8
'class'=9
'const'=10
'continue'=11
'default'=12
'do'=13
'double'=14
'else'=15
'enum'=16
'extends'=17
'final'=18
'finally'=19
'float'=20
'for'=21
'if'=22
'goto'=23
'implements'=24
'import'=25
'instanceof'=26
'int'=27
'interface'=28
'long'=29
'native'=30
'new'=31
'package'=32
'private'=33
'protected'=34
'public'=35
'return'=36
'short'=37
'static'=38
'strictfp'=39
'super'=40
'switch'=41
'synchronized'=42
'this'=43
'throw'=44
'throws'=45
'transient'=46
'try'=47
'void'=48
'volatile'=49
'while'=50
'module'=51
'open'=52
'requires'=53
'exports'=54
'opens'=55
'to'=56
'uses'=57
'provides'=58
'with'=59
'transitive'=60
'var'=61
'yield'=62
'record'=63
'sealed'=64
'permits'=65
'non-sealed'=66
'null'=77
'('=78
')'=79
'{'=80
'}'=81
'['=82
']'=83
';'=84
','=85
'.'=86
'='=87
'>'=88
'<'=89
'!'=90
'~'=91
'?'=92
':'=93
'=='=94
'<='=95
'>='=96
'!='=97
'&&'=98
'||'=99
'++'=100
'--'=101
'+'=102
'-'=103
'*'=104
'/'=105
'&'=106
'|'=107
'^'=108
'%'=109
'+='=110
'-='=111
'*='=112
'/='=113
'&='=114
'|='=115
'^='=116
'%='=117
'<<='=118
'>>='=119
'>>>='=120
'->'=121
'::'=122
'@'=123
'...'=124
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
REPO="https://gitea.hb.dhbw-stuttgart.de/f.holzwarth/JavaCompilerCore.git"
TDIR="./testBuild"
rm -rf "$TDIR" 2>/dev/null
mkdir $TDIR
cd $TDIR
git clone $REPO .
git checkout feat/unify-server
# git checkout 93e1a8787cd94c73f4538f6a348f58613893a584
# git checkout dad468368b86bdd5a3d3b2754b17617cee0a9107 # 1:55
# git checkout a0c11b60e8c9d7addcbe0d3a09c9ce2924e9d5c0 # 2:25
# git checkout 4cddf73e6d6c9116d3e1705c4b27a8e7f18d80c3 # 2:27
# git checkout 6c2d97b7703d954e4a42eef3ec374bcf313af75c # 2:13
# git checkout f722a00fbb6e69423d48a890e4a6283471763e64 # 1:35
# git checkout f0a4a51ce65639ce9a9470ff0fdb538fdf9c02cc # 2:19
# git checkout 1391206dfe59263cdb22f93371cfd1dd5465d97f # 1:29
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
mvn clean compile -DskipTests package
time java -jar target/JavaTXcompiler-0.1-jar-with-dependencies.jar resources/bytecode/javFiles/Matrix.jav;
# mvn clean compile test
echo -e "\nCleanup... "
cd -
rm -rf "$TDIR" 2>/dev/null
echo -e "\nFinished "
date "+%Y.%m.%d %H:%M:%S"
echo -e "\n "
+59 -16
View File
@@ -12,60 +12,103 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>4.11</version> <version>5.13.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 --> <!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
<dependency> <dependency>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId> <artifactId>antlr4</artifactId>
<version>4.11.1</version> <version>4.13.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.6</version> <version>2.19.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.github.classgraph</groupId> <groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId> <artifactId>classgraph</artifactId>
<version>4.8.172</version> <version>4.8.180</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>33.2.0-jre</version> <version>33.4.8-jre</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm --> <!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency> <dependency>
<groupId>org.ow2.asm</groupId> <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId> <artifactId>asm</artifactId>
<version>9.5</version> <version>9.8</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>com.diogonunes</groupId>
<artifactId>JColor</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.jcommander</groupId>
<artifactId>jcommander</artifactId>
<version>3.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.13</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version> <version>3.14.0</version>
<configuration> <configuration>
<compilerArgs>--enable-preview</compilerArgs> <source>25</source>
<source>22</source> <target>25</target>
<target>22</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.1.0</version> <version>3.5.3</version>
<configuration> <configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile> <redirectTestOutputToFile>true</redirectTestOutputToFile>
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory> <reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
<argLine>--enable-preview</argLine> <argLine>${argLine} --enable-preview</argLine>
<trimStackTrace>false</trimStackTrace> <trimStackTrace>false</trimStackTrace>
<excludes> <excludes>
<exclude>**/JavaTXCompilerTest.java</exclude> <exclude>**/JavaTXCompilerTest.java</exclude>
@@ -77,7 +120,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<plugin> <plugin>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId> <artifactId>antlr4-maven-plugin</artifactId>
<version>4.11.1</version> <version>4.13.2</version>
<executions> <executions>
<execution> <execution>
<id>antlr</id> <id>antlr</id>
@@ -90,7 +133,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version> <version>3.4.2</version>
<configuration> <configuration>
<archive> <archive>
<manifest> <manifest>
+10
View File
@@ -0,0 +1,10 @@
public class Bar{
void visit(Object o){
System.out.println("Object");
}
void visit(Bla f){
System.out.println("Foo");
}
}
+8 -4
View File
@@ -1,8 +1,12 @@
class Box<A> { public class Box {
A a; a;
public Box(A a) { public Box() { }
this.a = a; public Box(a) {
//this.a = a;
}
set(x) {
a = x;
} }
} }
+6
View File
@@ -0,0 +1,6 @@
public class Foo{
public accept(Bar b){
b.visit(this);
}
}
+15
View File
@@ -0,0 +1,15 @@
import java.lang.Integer;
public class Assign {
public x = 10;
public y = this;
public call() {
return this;
}
public m() {
this.call().call().y.x = 20;
return x;
}
}
-3
View File
@@ -1,3 +0,0 @@
class Box<A> {
void m(A a) { }
}
+1 -1
View File
@@ -6,7 +6,7 @@ import java.util.stream.Stream;
public class Bug325 { public class Bug325 {
public main() { public main() {
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5)); var list = new ArrayList<>(List.of(1,2,3,4,5));
var func = x -> x*2; var func = x -> x*2;
return list.stream().map(func).toList(); return list.stream().map(func).toList();
} }
+2
View File
@@ -0,0 +1,2 @@
public record Bug343() {
}
+22
View File
@@ -0,0 +1,22 @@
import java.lang.String;
public class Bug363 {
uncurry (f){
return x -> f.apply(x);
}
uncurry (f){
return (x, y) -> f.apply(x).apply(y);
}
uncurry (f){
return (x, y, z) -> f.apply(x).apply(y).apply(z);
}
public test(){
var f = x -> y -> z -> x + y + z;
var g = uncurry(f);
return g.apply("A", "B", "C"); // Outputs: 6
}
}
+8
View File
@@ -0,0 +1,8 @@
import java.lang.String;
public class Bug364{
public main(){
var f = x -> y -> z -> x + y + z;
return f.apply("A").apply("B").apply("C");
}
}
+21
View File
@@ -0,0 +1,21 @@
import java.lang.String;
import java.lang.Object;
public class Bug365{
swap(f){
return x -> y -> f.apply(y).apply(x);
}
swap(Fun1$$<String, Fun1$$<String, Fun1$$<String, Object>>> f){
return x -> y -> z -> f.apply(z).apply(y).apply(x);
}
public ex1() {
var func = x -> y -> z -> x + y + z;
return func.apply("A").apply("B").apply("C");
}
public ex2() {
var func = x -> y -> z -> x + y + z;
return swap(func).apply("A").apply("B").apply("C");
}
}
+12
View File
@@ -0,0 +1,12 @@
import java.lang.Integer;
public class Bug366 {
public static lambda() {
return (a, b) -> a + b;
}
public static test() {
var l = lambda();
return l.apply(10, 20);
}
}
+10
View File
@@ -0,0 +1,10 @@
import java.lang.Boolean;
public class Bug371 {
static m1(x, y) { return x || y; }
static m2(x, y) { return x && y; }
public static test() {
return m2(m1(true, false), true);
}
}
+17
View File
@@ -0,0 +1,17 @@
import java.lang.Boolean;
import java.lang.Integer;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Character;
public class Bug373 {
public static main() {
System.out.println(true);
System.out.println(false);
System.out.println(1);
System.out.println(1l);
System.out.println(1.0);
System.out.println(1.0f);
System.out.println('a');
}
}
+3
View File
@@ -0,0 +1,3 @@
class Bug378Id {
id2 = x -> x;
}
@@ -0,0 +1,8 @@
import Bug378Id;
import java.lang.Integer;
public class Bug378Main {
public static main(args) {
var hallo = (new Bug378Id<Integer>().id2).apply(1);
}
}
+24
View File
@@ -0,0 +1,24 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.System;
import java.io.PrintStream;
public class Bug379 {
public Fun1$$<Double, Double> fact = (x) -> {
if (x == 1) {
return 1;
} else {
return x * (fact.apply(x-1));
}
};
public getFact(x) {
return fact.apply(x);
}
public static void main(x) {
var f = new Bug379();
var intRes = f.getFact(3);
System.out.println(intRes);
}
}
+12
View File
@@ -0,0 +1,12 @@
sealed interface List<T> permits Cons, Empty {}
record Cons<T>(T a , List<T> l ) implements List <T> {}
record Empty<T>() implements List <T> {}
public class Bug380 {
public <T> List<T> append(l1, List<T> l2) {
return switch ( l1 ) {
case Cons(e, rest) -> new Cons<>(e, append(rest, l2)); //::Typ TPH A
case Empty() -> l2;//::TPH B
};
}
}
+13
View File
@@ -0,0 +1,13 @@
import java.lang.Runnable;
import java.lang.String;
import java.lang.System;
import java.io.PrintStream;
import java.lang.Thread;
public class Bug382 {
public static main(a) {
var f = () -> System.out.println("Hallo Welt!");
new Thread(f).run();
}
}
+10
View File
@@ -0,0 +1,10 @@
import java.lang.String;
import java.lang.System;
import java.io.PrintStream;
public class Bug383 {
public static main(a) {
var f = () -> System.out.println("Hello from Thread!");
f.apply();
}
}
+8
View File
@@ -0,0 +1,8 @@
import java.lang.Math;
import java.lang.Double;
public class Bug390 {
public static main(args) {
var pi = Math.PI;
}
}
-16
View File
@@ -1,16 +0,0 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.lang.String;
import java.util.stream.Stream;
import java.util.function.Function;
import java.util.function.Predicate;
import java.lang.Integer;
class BugXXX {
public main() {
List<Integer> i = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
Optional<Integer> tmp = i.stream().filter(x -> x == 5).map(x -> x*2).findFirst();
return tmp;
}
}
@@ -0,0 +1 @@
public record GenericRecord<T>(T a) {}
@@ -0,0 +1,24 @@
import java.lang.String;
import java.lang.Integer;
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem<T>(T a,List l) implements List{}
public record Elem<T>(T c) implements List{}
public class GenericRecordSwitchCase {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a ;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a;
};
}
}
+14
View File
@@ -0,0 +1,14 @@
import java.lang.Object;
import java.lang.System;
import java.lang.Iterable;
import java.io.PrintStream;
import java.util.List;
import java.lang.String;
class Main {
static main(args) {
for (var arg : args) {
System.out.println(arg);
}
}
}
+6 -12
View File
@@ -4,16 +4,10 @@ import java.lang.Double;
import java.util.Vector; import java.util.Vector;
import java.lang.Boolean; import java.lang.Boolean;
public class OLFun { public class OLFun {
m(f) {
//f = x -> {return x + x;}; var x;
m(f, x) { x = f.apply(x + x);
x = f.apply(x+x); return x;
return x; }
}
m2(y) {
m(x -> x * 2, y);
return;
}
} }
-13
View File
@@ -1,13 +0,0 @@
import java.lang.String;
import java.lang.Integer;
import java.lang.Double;
import java.util.Vector;
import java.lang.Boolean;
public class OLFun2 {
x;
m(f){
x = f.apply(x + x);
}
}
@@ -0,0 +1,20 @@
import java.lang.Object;
import java.lang.Integer;
import java.lang.Float;
public record R(Object nested) {}
public class OverloadNestedPattern {
public Integer m(R(R(Integer a)), R(Integer b)) {
return 1;
}
public Integer m(R(R(Float a)), R(Float b)) {
return 2;
}
public Integer m(R(Integer a), R(Integer b)) {
return 3;
}
}
@@ -2,15 +2,31 @@ import java.lang.Integer;
import java.lang.Number; import java.lang.Number;
import java.lang.Float; import java.lang.Float;
record Point(Number x, Number y) {} public record Point(Number x, Number y) {}
public class OverloadPattern { public class OverloadPattern {
public m(Point(Integer x, Integer y)) { public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
return x + y; return 1;
} }
public m(Point(Float x, Float y)) { public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) {
return x * y; return 2;
}
public Number m(Point(Float x, Float y), Point(Integer a, Integer b)) {
return 3;
}
public Number m(Point(Float x, Float y), Point(Float a, Float b)) {
return 4;
}
public Number m(Point(Integer x, Integer y)) {
return 5;
}
public Number m(Point(Float x, Float y)) {
return 6;
} }
public m(Integer x) { public m(Integer x) {
@@ -0,0 +1,25 @@
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public record Tuple<T1, T2>(T1 a, T2 b) {}
public class PatternMatching {
public zip(Cons(x, xs), Cons(y, ys)) {
return new Cons(new Tuple(x, y), zip(xs, ys));
}
public zip(Empty x, Empty y) { return new Empty(); }
/*public zip(Empty x, Cons y) { return new Empty(); }
public zip(Cons x, Empty y) { return new Empty(); }
public zip(Empty x, Empty y) { return new Empty(); }
*/
/*
Generiert:
Cons zip<T>(Cons(T x, Cons xs), Cons(T y, Cons ys))
Cons zip<T>(Cons(T x, Cons xs), Cons(T y, Empty ys))
Cons zip<T>(Cons(T x, Empty xs), Cons(T y, Cons ys))
Cons zip<T>(Cons(T x, Empty xs), Cons(T y, Empty ys))
*/
}
@@ -0,0 +1,21 @@
import java.lang.Boolean;
sealed interface List<T> permits LinkedElem, Elem {}
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
public record Elem<T>(T a) implements List<T> {}
public class PatternMatchingHaskellStyle {
public append(LinkedElem(a, b), list2) {
return handleAppend(a, b, list2);
}
private handleAppend(a, Elem(e), list2) {
return new LinkedElem<>(a, new LinkedElem<>(e, list2));
}
private handleAppend(a, LinkedElem(e,r), list2) {
return new LinkedElem<>(a, append(new LinkedElem(e, r), list2));
}
}
@@ -0,0 +1,19 @@
import java.lang.Object;
import List;
import Cons;
import Empty;
import Tuple;
public class PatternMatchingJava {
public zip(a, b) {
switch (a) {
case Cons(x, Cons xs) -> {
switch (b) {
case Cons(y, Cons ys) -> { return new Cons<>(new Tuple<>(x, y), zip(xs, ys)); }
case Cons(y, Empty()) -> { return new Empty<>(); }
};
}
case Cons(x, Empty()) -> { return new Empty<>(); }
};
}
}
@@ -0,0 +1,5 @@
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public record Tuple<T1, T2>(T1 a, T2 b) {}
@@ -0,0 +1,26 @@
import java.lang.Boolean;
import java.lang.Object;
sealed interface List<T> permits Cons, Empty {}
public record Cons<T>(T a, List<T> l) implements List<T> {}
public record Empty<T>() implements List<T> {}
public class PatternMatchingListAppend {
public append(Cons(a, b), list2) {
return new Cons<>(a, append(b, list2));
}
public append(Empty(), list2) {
return list2;
}
/*public append(a, list2) {
switch(a) {
case Cons(x, y) -> ...
case Empty() ->
}
}*/
}
@@ -0,0 +1,18 @@
import java.lang.Integer;
import java.lang.String;
public record R(String n) {}
public class SwitchOverload {
f() { return 10; }
g() { return 20; }
public m(r) {
return switch(r) {
case R("test") -> f();
case R("foo") -> g();
case R r -> 0;
};
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ public class Switch {
case Rec(Integer a, Float b) -> a + 10; case Rec(Integer a, Float b) -> a + 10;
case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c; case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c;
case Integer i -> i; case Integer i -> i;
default -> 0; //default -> 0;
}; };
} }
} }
@@ -0,0 +1,16 @@
sealed interface List<T> permits LinkedElem, Elem {}
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
public record Elem<T>(T a) implements List<T> {}
public class SwitchAppend {
public append(l1, l2) {
return switch(l1) {
case LinkedElem(a, Elem(e)) -> new LinkedElem<>(a, new LinkedElem<>(e, l2));
case LinkedElem(a, r) -> new LinkedElem<>(a, append(r, l2));
//Alternativ:
//case LinkedElem(a, LinkedElem(e, r)) -> new LinkedElem<>(a, append(new LinkedElem(e, r), l2));
//default -> null;
};
}
}
@@ -0,0 +1,22 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
public class NumberOrText{}
public class Text extends NumberOrText{};
public class Number extends NumberOrText{};
public record Cons(Integer a, NumberOrText l){}
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case Cons(a, Text b) -> "Second Element is a Text";
case Cons(a, Number b) -> "Second Element is a Number";
default -> "None of the above cases";
};
}
}
@@ -0,0 +1,17 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
public record Rec(Object a, Object b) {}
public class SwitchInfered {
public main(o) {
return switch (o) {
case Rec(a, b) -> "asd";
default -> "cde";
};
}
}
@@ -0,0 +1,14 @@
import java.lang.Object;
import java.lang.Integer;
public record R(Integer i) {}
public class SwitchNestedValue {
public main(r) {
return switch(r) {
case R(10) -> 1;
case R(20) -> 2;
case R(i) -> 3;
};
}
}
@@ -0,0 +1,21 @@
import java.lang.Integer;
import java.lang.Double;
import java.lang.Number;
public record R(Number n) {}
public class SwitchOverload {
Number f(Double d) { return d * 2; }
Number f(Integer i) { return i * 5; }
public m(r, x) {
x = x + x;
return switch(r) {
case R(o) -> {
x = x + x;
yield f(o);
}
};
}
}
@@ -0,0 +1,27 @@
import java.lang.Integer;
import java.lang.Object;
import java.lang.Float;
import java.lang.String;
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet
public record Elem(Integer c) implements List{} //Implementiert List, wird aber nicht permittet
public class SwitchCaseHeritageDetection {
public main(o) {
return switch(o) {
case LinkedElem(a, Elem(e)) -> a + e;
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a + e + f;
default -> 0;
};
}
}
+9 -29
View File
@@ -2,41 +2,21 @@ import java.lang.Integer;
public class Y { public class Y {
y; y;
//factorial;
public Y() { public Y() {
y = f -> t -> f.apply(y.apply(f)).apply(t); y = f -> t -> f.apply(y.apply(f)).apply(t);
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}
/*
getY() {
return y;
}
*/
}
/*
class fac1 {
factorial;
fac1() {
var y;
y = new Y<Integer,Integer,Integer,Integer,Integer>().getY();
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
} }
} }
ergibt Parse-Error public class Fac1 {
class fac1 { public factorial;
factorial; public Fac1() {
fac1() {
var y; var y;
y = new Y<>().y; var tmp = new Y<>(); // TODO Having new Y<>().y on one line doesn't work, see FIXME in StatementGenerator
y = tmp.y;
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
} }
public static void main(String args[]) {
System.out.println(new fac1().factorial.apply(3));
}
public fac(v) {
return factorial.apply(v);
}
} }
*/
@@ -654,14 +654,17 @@ primaryPattern
: typePattern #tPattern : typePattern #tPattern
| recordPattern #rPattern | recordPattern #rPattern
| '(' pattern ')' #enclosedPattern | '(' pattern ')' #enclosedPattern
| literal (',' literal)* #lPattern
; ;
recordPattern recordPattern
: typeType recordStructurePattern identifier? : typeType recordStructurePattern identifier?
//| recordStructurePattern identifier?
; ;
typePattern typePattern
: variableModifier* typeType identifier : variableModifier* typeType identifier
| variableModifier* identifier
; ;
recordStructurePattern recordStructurePattern
@@ -717,10 +720,10 @@ switchLabeledRule
; ;
switchLabelCase switchLabelCase
: CASE expressionList (ARROW | COLON) #labeledRuleExprList : CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE pattern (ARROW | COLON) #labeledRulePattern | CASE pattern (ARROW | COLON) #labeledRulePattern
| DEFAULT (ARROW | COLON) #labeledRuleDefault | DEFAULT (ARROW | COLON) #labeledRuleDefault
| CASE expressionList (ARROW | COLON) #labeledRuleExprList
; ;
// Java20 // Java20
File diff suppressed because it is too large Load Diff
@@ -1,11 +1,13 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.syntaxtree.statement.Break;
import de.dhbwstuttgart.target.tree.TargetGeneric; import de.dhbwstuttgart.target.tree.TargetGeneric;
import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.target.tree.type.*;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import java.sql.Array;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -35,19 +37,37 @@ public class FunNGenerator {
public List<TargetType> parameters = new ArrayList<>(); public List<TargetType> parameters = new ArrayList<>();
final String descriptor; final String descriptor;
public final List<TargetType> inParams; public final List<TargetType> inParams;
public final List<TargetType> realParams;
public GenericParameters(TargetFunNType funNType) {
this(funNType.funNParams(), funNType.returnArguments());
}
public GenericParameters(List<TargetType> params, int numReturns) { public GenericParameters(List<TargetType> params, int numReturns) {
this.inParams = params; this.realParams = params;
this.inParams = flattenTypeParams(params);
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params); var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
descriptor = applyDescriptor(type, this); descriptor = applyDescriptor(type, this);
} }
private static List<TargetType> flattenTypeParams(List<TargetType> params) {
var res = new ArrayList<TargetType>();
for (var param : params) {
if (param instanceof TargetSpecializedType tspec) {
res.addAll(flattenTypeParams(tspec.params()));
} else {
res.add(param);
}
}
return res;
}
public TargetType getReturnType() { public TargetType getReturnType() {
return FunNGenerator.getReturnType(inParams); return FunNGenerator.getReturnType(realParams);
} }
public List<TargetType> getArguments() { public List<TargetType> getArguments() {
return FunNGenerator.getArguments(inParams); return FunNGenerator.getArguments(realParams);
} }
} }
@@ -55,7 +75,7 @@ public class FunNGenerator {
if (type == null) return VOID; if (type == null) return VOID;
var res = "L" + type.getInternalName(); var res = "L" + type.getInternalName();
if (type instanceof TargetSpecializedType a) { if (type instanceof TargetSpecializedType a) {
if (a.params().size() > 0) { if (!a.params().isEmpty() && !(a.params().size() == 1 && a.params().getFirst() == null)) {
res += "<"; res += "<";
for (var param : a.params()) { for (var param : a.params()) {
if (param instanceof TargetGenericType gp) { if (param instanceof TargetGenericType gp) {
@@ -78,7 +98,7 @@ public class FunNGenerator {
} }
private static String applySignature(TargetType a) { return a.toSignature(); } private static String applySignature(TargetType a) { return a.toSignature(); }
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); } private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); }
public static String encodeType(TargetType type) { public static String encodeType(TargetType type) {
if (type == null) return VOID; if (type == null) return VOID;
@@ -95,16 +115,17 @@ public class FunNGenerator {
superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter)); superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter));
superFunNMethodDescriptor.append(objectSignature); superFunNMethodDescriptor.append(objectSignature);
} }
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
if (numReturnTypes > 0) { if (numReturnTypes > 0) {
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric)); superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature)); superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
} else { } else {
superFunNClassSignature = new StringBuilder(objectSignature);
superFunNMethodSignature.append(")V"); superFunNMethodSignature.append(")V");
superFunNMethodDescriptor.append(")V"); superFunNMethodDescriptor.append(")V");
} }
System.out.println(superFunNMethodSignature); Codegen.logger.info(superFunNMethodSignature);
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor; MethodVisitor methodVisitor;
@@ -162,7 +183,7 @@ public class FunNGenerator {
} }
public static String getSpecializedClassName(GenericParameters gep) { public static String getSpecializedClassName(GenericParameters gep) {
return getSpecializedClassName(getArguments(gep.inParams), getReturnType(gep.inParams)); return getSpecializedClassName(gep.getArguments(), gep.getReturnType());
} }
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) { public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
@@ -1,46 +1,83 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.util.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.*; import java.util.*;
public class ConsoleInterface {
private static final String directory = System.getProperty("user.dir");
public static void main(String[] args) throws IOException, ClassNotFoundException {
List<File> input = new ArrayList<>();
List<File> classpath = new ArrayList<>();
String outputPath = null;
Iterator<String> it = Arrays.asList(args).iterator();
if(args.length == 0){
System.out.println("No input files given. Get help with --help");
System.exit(1);
}else if(args.length == 1 && args[0].equals("--help")){
System.out.println("Usage: javatx [OPTION]... [FILE]...\n" +
"\t-cp\tSet Classpath\n" +
"\t-d\tSet destination directory");
System.exit(1);
}
while(it.hasNext()){
String arg = it.next();
if(arg.equals("-d")){
outputPath = it.next();
}else if(arg.startsWith("-d")) {
outputPath = arg.substring(2);
}else if(arg.equals("-cp") || arg.equals("-classpath")){
String[] cps = it.next().split(":");
for(String cp : cps){
classpath.add(new File(cp));
}
}else{
input.add(new File(arg));
}
}
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath, outputPath != null ? new File(outputPath) : null);
//compiler.typeInference();
compiler.generateBytecode();
}
class Args {
@Parameter(description = "Set destination directory", names = "-d")
File outputPath;
@Parameter(description = "Set class path", names = {"-cp", "-classpath"})
String classpath;
@Parameter(description = "[FILE]...")
List<File> input;
@Parameter(description = "Server mode", names = "--server-port")
Integer serverPort;
@Parameter(description = "Unify server url", names = "--unify-server")
String serverUrl;
@Parameter(description = "Write logs", names = "--write-logs")
boolean writeLogs = false;
@Parameter(names = "-v", description = "Verbosity level")
int verbosity = 0;
@Parameter(names = "--infer-together", description = "Runs the type inference on all input files together instead of sequentially")
boolean inferTogether = false;
@Parameter(names = "--help", help = true)
boolean help;
}
public class ConsoleInterface {
public static Logger.LogLevel logLevel = Logger.LogLevel.ERROR;
public static boolean writeLogFiles = false;
public static boolean inferTogether = false;
public static Optional<String> unifyServerUrl = Optional.empty();
public static void main(String[] argv) throws IOException, ClassNotFoundException {
var args = new Args();
var builder = JCommander.newBuilder().addObject(args).build();
builder.setProgramName("javatx");
try {
builder.parse(argv);
if (args.help) {
builder.usage();
return;
}
} catch (ParameterException e) {
System.err.println(e.getMessage());
System.err.println();
builder.usage();
System.exit(1);
}
inferTogether = args.inferTogether;
unifyServerUrl = Optional.ofNullable(args.serverUrl);
writeLogFiles = args.writeLogs;
switch (args.verbosity) {
case 1 -> logLevel = Logger.LogLevel.WARNING;
case 2 -> logLevel = Logger.LogLevel.INFO;
case 3 -> logLevel = Logger.LogLevel.DEBUG;
default -> logLevel = Logger.LogLevel.ERROR;
}
if (args.serverPort != null) {
if (unifyServerUrl.isPresent()) throw new RuntimeException("Cannot use unifyServer when in server mode!");
JavaTXServer server = new JavaTXServer(args.serverPort);
server.listen();
} else {
if (args.input == null) {
System.err.println("No input files given. Get help with --help");
System.exit(1);
}
List<File> classpath = args.classpath == null ? List.of() : Arrays.stream(args.classpath.split(File.pathSeparator)).map(File::new).toList();
JavaTXCompiler compiler = new JavaTXCompiler(args.input, classpath, args.outputPath, inferTogether);
compiler.generateBytecode();
SocketClient.closeIfOpen();
}
}
} }
@@ -2,16 +2,24 @@
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.Codegen; import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.bytecode.FunNGenerator;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader; import de.dhbwstuttgart.environment.DirectoryClassLoader;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext; 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.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;
@@ -35,10 +43,13 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.RuleSet; import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.distributeVariance; import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
@@ -49,9 +60,11 @@ import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel; import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import de.dhbwstuttgart.util.Logger;
import java.io.*; import java.io.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.file.Path; import java.nio.file.Path;
import java.sql.Array;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.Function; import java.util.function.Function;
@@ -61,49 +74,89 @@ import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler { public class JavaTXCompiler {
// do not use this in any code, that can be executed serverside!
public static PlaceholderRegistry defaultClientPlaceholderRegistry = new PlaceholderRegistry();
public static Logger defaultLogger = new Logger();
private final boolean inferTogether;
// public static JavaTXCompiler INSTANCE; // public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean resultmodel = true; Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>(); public final Map<File, SourceFile> sourceFiles = new HashMap<>();
public final Set<JavaClassName> input = new HashSet<>();
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll? public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); public final DirectoryClassLoader classLoader;
public final DirectoryClassLoader classLoader;
public final List<File> classPath; public final List<File> classPath;
private final File outputPath; private final File outputPath;
public final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
public final Set<Integer> usedFunNSuperTypes = new HashSet<>();
private final Map<JavaClassName, ClassOrInterface> loadedClasses = new HashMap<>();
public Map<String, byte[]> auxiliaries = new HashMap<>();
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(Arrays.asList(sourceFile), List.of(), new File(".")); this(Collections.singletonList(sourceFile), List.of(), new File("."), ConsoleInterface.inferTogether);
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
} }
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("."), ConsoleInterface.inferTogether);
} }
public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sources, List<File> contextPath, File outputPath, boolean inferTogether) throws IOException, ClassNotFoundException {
// ensure new default placeholder registry for tests
defaultClientPlaceholderRegistry = new PlaceholderRegistry();
this.inferTogether = inferTogether;
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
path.add(new File(System.getProperty("user.dir"))); path.add(new File(System.getProperty("user.dir")));
} }
if (outputPath != null) path.add(outputPath); if (outputPath != null) path.add(outputPath);
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader()); classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader().getParent());
environment = new CompilationEnvironment(sources, classLoader); environment = new CompilationEnvironment(sources, classLoader);
classPath = path; classPath = path;
this.outputPath = outputPath; this.outputPath = outputPath;
for (File s : sources) { // TODO This should maybe be moved elsewhere
parse(s); var treeList = new ArrayList<SourceFileContext>(sources.size());
for (var s : sources) {
var tree = (Java17Parser.SrcfileContext) JavaTXParser.parse(s);
treeList.add(tree);
// Find defined classes
var pkgName = tree.packageDeclaration() != null ? tree.packageDeclaration().qualifiedName().getText(): "";
for (var ctx : tree.classOrInterface()) {
if (ctx instanceof Java17Parser.NoclassorinterfaceContext) continue;
var classContext = (Java17Parser.ClassorinterfacedeclContext) ctx;
String name = null;
Java17Parser.GenericDeclarationListContext decl = null;
if (classContext.classDeclaration() != null) {
name = classContext.classDeclaration().identifier().getText();
decl = classContext.classDeclaration().genericDeclarationList();
} else if (classContext.recordDeclaration() != null) {
name = classContext.recordDeclaration().identifier().getText();
decl = classContext.recordDeclaration().genericDeclarationList();
} else if (classContext.interfaceDeclaration() != null) {
name = classContext.interfaceDeclaration().identifier().getText();
decl = classContext.interfaceDeclaration().genericDeclarationList();
}
var numberOfGenerics = decl == null ? 0 : decl.genericTypeVar().size();
var className = pkgName + (!pkgName.isEmpty() ? "." : "") + name;
classRegistry.addName(className, numberOfGenerics);
input.add(classRegistry.getName(className));
}
}
for (var i = 0; i < sources.size(); i++) {
parse(treeList.get(i), sources.get(i));
} }
// INSTANCE = this; // INSTANCE = this;
} }
@@ -113,21 +166,26 @@ public class JavaTXCompiler {
} }
public ClassOrInterface getClass(JavaClassName name) { public ClassOrInterface getClass(JavaClassName name) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif(); if (loadedClasses.containsKey(name)) return loadedClasses.get(name);
for (var sf : sourceFiles.values()) { for (var sf : sourceFiles.values()) {
for (var clazz : sf.KlassenVektor) { for (var clazz : sf.KlassenVektor) {
if (clazz.getClassName().equals(name)) return clazz; if (clazz.getClassName().equals(name)) return clazz;
} }
} }
if (input.contains(name)) return null;
try { try {
var clazz = classLoader.loadClass(name.toString()); var clazz = classLoader.loadClass(name.toString());
if (clazz != null) ClassOrInterface cif = null;
return ASTFactory.createClass(clazz); if (clazz != null) {
cif = ASTFactory.createClass(clazz);
loadedClasses.put(name, cif);
}
return cif;
} catch (ClassNotFoundException ignored) {} } catch (ClassNotFoundException ignored) {}
return null; return null;
} }
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException { public Set<ClassOrInterface> getAvailableClasses(File sourceFile) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses(); Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(Object.class); ClassOrInterface objectClass = ASTFactory.createClass(Object.class);
var recordClass = ASTFactory.createClass(Record.class); var recordClass = ASTFactory.createClass(Record.class);
@@ -153,7 +211,7 @@ public class JavaTXCompiler {
for (var clazz : sf.availableClasses) { for (var clazz : sf.availableClasses) {
if (loadedClasses.containsKey(clazz.getClassName())) { if (loadedClasses.containsKey(clazz.getClassName())) {
allClasses.removeIf(cl -> cl.getClassName().equals(clazz.getClassName())); allClasses.removeIf(cl -> cl.getClassName().equals(clazz.getClassName()));
var cif = loadedClasses.get(clazz.getClassName()).cif(); var cif = loadedClasses.get(clazz.getClassName());
allClasses.add(cif); allClasses.add(cif);
isCached = true; isCached = true;
} }
@@ -166,7 +224,13 @@ public class JavaTXCompiler {
allClasses.addAll(sf.KlassenVektor); allClasses.addAll(sf.KlassenVektor);
TYPE ty = new TYPE(sf, allClasses); return allClasses;
}
public ConstraintSet<Pair> getConstraints(File sourceFile) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(sourceFile);
var allClasses = getAvailableClasses(sourceFile);
TYPE ty = new TYPE(new HashSet<>(sf.availableClasses), allClasses);
var constraints = ty.getConstraints(); var constraints = ty.getConstraints();
return constraints; return constraints;
} }
@@ -186,8 +250,9 @@ public class JavaTXCompiler {
try { try {
var className = cl.getSuperClass().getName().toString(); var className = cl.getSuperClass().getName().toString();
superclass = ASTFactory.createClass(classLoader.loadClass(className)); superclass = ASTFactory.createClass(classLoader.loadClass(className));
} catch (ClassNotFoundException ignored) {} } catch (ClassNotFoundException e) {
// throw new ClassNotFoundException(""); throw new RuntimeException(e);
}
} }
} }
@@ -216,13 +281,18 @@ public class JavaTXCompiler {
private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException { private Set<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>(); Set<ClassOrInterface> allClasses = new HashSet<>();
var clazz = loadJavaTXClass(name); if (input.contains(name)) {
if (clazz == null) { for (var sf : sourceFiles.values()) {
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString())); for (var cif : sf.KlassenVektor) {
allClasses.add(importedClass); if (cif.getClassName().equals(name)) {
} else { allClasses.add(cif);
allClasses.add(clazz); return allClasses;
}
}
}
} }
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
return allClasses; return allClasses;
} }
@@ -300,126 +370,193 @@ public class JavaTXCompiler {
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = null; UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener); // urm.addUnifyResultListener(resultListener);
try { logFile = logFile == null ? new FileWriter("log_" + sourceFiles.keySet().iterator().next().getName()) : logFile;
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile; Logger logger = new Logger(logFile, "TypeInferenceAsync");
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader(), this); UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, defaultClientPlaceholderRegistry);
System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> { IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logger, getClassLoader(), this, context.placeholderRegistry());
UnifyType lhs, rhs; logger.info(finiteClosure.toString());
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) { urm = new UnifyResultModel(cons, finiteClosure);
((PlaceholderType) lhs).setInnerType(true); urm.addUnifyResultListener(resultListener);
((PlaceholderType) rhs).setInnerType(true); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
}
return x;
}; Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
logFile.write(unifyCons.toString()); UnifyType lhs, rhs;
unifyCons = unifyCons.map(distributeInnerVars); if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
logFile.write(unifyCons.toString()); ((PlaceholderType) lhs).setInnerType(true);
TypeUnify unify = new TypeUnify(); ((PlaceholderType) rhs).setInnerType(true);
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile f : this.sourceFiles.values()) {
logFile.write(ASTTypePrinter.print(f));
} }
logFile.flush(); return x;
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> { };
a.addAll(b); logger.debug(unifyCons.toString());
return a; unifyCons = unifyCons.map(distributeInnerVars);
}, (a, b) -> { logger.debug(unifyCons.toString());
a.addAll(b); // Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
return a; logger.debug("FC:\\" + finiteClosure.toString() + "\n");
})).reduce(new HashSet<String>(), (a, b) -> { for (SourceFile f : this.sourceFiles.values()) {
a.addAll(b); logger.debug(ASTTypePrinter.print(f));
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames);
unifyCons = unifyCons.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
*/;
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
} catch (IOException e) {
System.err.println("kein LogFile");
} }
// logFile.flush();
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
* .stream().map(x -> { Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors. toCollection(ArrayList::new))
*/;
TypeUnify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
return urm; return urm;
} }
public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException { public List<ResultSet> typeInference(File file) throws ClassNotFoundException, IOException {
return typeInference(List.of(file));
}
public List<ResultSet> typeInference(List<File> files) throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();
var ressf = new ArrayList<SourceFile>();
var definedClasses = new HashSet<ClassOrInterface>();
for (var file : files) {
var sf = sourceFiles.get(file);
definedClasses.addAll(sf.KlassenVektor);
ressf.add(sf);
allClasses.addAll(getAvailableClasses(file));
allClasses.addAll(sf.availableClasses);
}
TYPE ty = new TYPE(definedClasses, allClasses);
var cons = ty.getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>();
PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry();
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
if (ConsoleInterface.writeLogFiles && !logFolder.mkdirs()) throw new RuntimeException("Could not create directory for log files: " + logFolder);
Writer logFile = ConsoleInterface.writeLogFiles ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
Logger logger = new Logger(logFile, "TypeInference");
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, placeholderRegistry);
logger.info(finiteClosure.toString());
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, placeholderRegistry);
logger.info("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true);
}
return x;
};
logger.debug("Unify:" + unifyCons.toString());
logger.info("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logger.debug("\nUnify_distributeInnerVars: " + unifyCons.toString());
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logger.debug("FC:\\" + finiteClosure.toString() + "\n");
for (var sf : ressf) logger.info(ASTTypePrinter.print(sf));
// logFile.flush();
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
.collect(Collectors.toList());
logger.info(andConstraintsSorted);
Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/*
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
/*
* 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()) {
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
SocketFuture<UnifyResultPacket> future = SocketClient.execute(
UnifyRequestPacket.create(finiteClosure, cons, unifyCons, context.placeholderRegistry())
);
SocketClient.execute(SetAutoclosePacket.create());
return future.get().getResultSet(context);
}
else if (resultmodel) {
/* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
UnifyContext context = new UnifyContext(logger, true, urm, usedTasks, placeholderRegistry);
TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
var finalResults = li.getResults().stream().sorted().toList();
int i = 0;
logger.info("RESULT Final: ");
for (var result : finalResults){
logger.info("Result: " + i++);
logger.info(result.getSortedResults());
}
logger.info("RES_FINAL: " + li.getResults().toString() + "\n");
return li.getResults();
}
/* UnifyResultModel End */
else {
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
// finiteClosure));
UnifyContext context = new UnifyContext(logger, false, new UnifyResultModel(cons, finiteClosure), usedTasks, placeholderRegistry);
Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
logger.info("RESULT: " + result);
results.addAll(result);
results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet(placeholderRegistry).subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y; // alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
} else
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
logger.info("RESULT Final: " + results);
logger.info("Constraints for Generated Generics: " + " ???");
logger.debug("RES_FINAL: " + results.toString() + "\n");
// logFile.flush();
logger.debug("PLACEHOLDERS: " + placeholderRegistry);
// logFile.flush();
}
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), placeholderRegistry)))).collect(Collectors.toList());
}
/**
* TEMPORARY - Only for Language Server Usage
*/
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
var sf = sourceFiles.get(file); var sf = sourceFiles.get(file);
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses(); if(sf == null){
sf = sourceFiles.values().stream().findFirst().get();
}
Set<ClassOrInterface> allClasses = new HashSet<>();
allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet()); var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
@@ -433,14 +570,13 @@ public class JavaTXCompiler {
final ConstraintSet<Pair> cons = getConstraints(file); final ConstraintSet<Pair> cons = getConstraints(file);
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
Writer logFile = new OutputStreamWriter(new NullOutputStream());
Logger logger = new Logger(logFile, "TypeInferenceAsync");
UnifyContext context = new UnifyContext(logger, false, null, usedTasks, defaultClientPlaceholderRegistry);
try { try {
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/"); IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logger, classLoader, this, context.placeholderRegistry());
if (log) logFolder.mkdirs(); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons, context.placeholderRegistry());
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
System.out.println("xxx1");
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> { Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
UnifyType lhs, rhs; UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) { if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
@@ -451,159 +587,48 @@ public class JavaTXCompiler {
}; };
logFile.write("Unify:" + unifyCons.toString());
System.out.println("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars); unifyCons = unifyCons.map(distributeInnerVars);
logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
logFile.write(ASTTypePrinter.print(sf));
System.out.println(ASTTypePrinter.print(sf));
logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames);
unifyCons = unifyCons.map(x -> {
// Hier muss ueberlegt werden, ob
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
// mit disableWildcardtable() werden.
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
// PL 2018-04-23
if ((x.getLhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
((PlaceholderType) x.getLhsType()).disableWildcardtable();
}
}
if ((x.getRhsType() instanceof PlaceholderType)) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
((PlaceholderType) x.getRhsType()).disableWildcardtable();
}
}
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
});
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
// variance 1 gesetzt
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
// Parameter die Typen der Argumente links stehen
// und die Typen der Rückgabewerte immer rechts stehen
/*
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> { if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { ((PlaceholderType) x.getLhsType()).setVariance((byte)1); } else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) { ((PlaceholderType) x.getRhsType()).setVariance((byte)-1); } })));
*/
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons); varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/* List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH); varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { if (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
* ((PlaceholderType)y.getRhsType()).getVariance() == 0) { ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType( )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType( )).getVariance()); } } return y; } ); } while (!varianceTPHold.equals(varianceTPH));
*/
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
/*
* Set<Set<UnifyPair>> ret = new HashSet<>(); for (Constraint<UnifyPair> y : x) { ret.add(new HashSet<>(y)); } return ret; }).collect(Collectors.toCollection(ArrayList::new))
*/;
if (resultmodel) { if (resultmodel) {
/* UnifyResultModel Anfang */ /* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure); UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl(); UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li); urm.addUnifyResultListener(li);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks); TypeUnify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
System.out.println("RESULT Final: " + li.getResults()); generateBytecode(sf, li.getResults());
System.out.println("Constraints for Generated Generics: " + " ???"); return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFile.flush();
return li.getResults();
} }
/* UnifyResultModel End */ /* UnifyResultModel End */
else { else {
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), Set<Set<UnifyPair>> result = TypeUnify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, context);
// oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
// finiteClosure));
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString() + "\n");
logFile.flush();
results.addAll(result); results.addAll(result);
results = results.stream().map(x -> { results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> { Optional<Set<UnifyPair>> res = new RuleSet(context.placeholderRegistry()).subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC) if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT); y.setPairOp(PairOperator.EQUALSDOT);
return y; // alle Paare a <.? b erden durch a =. b ersetzt return y; // alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new))); }).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); return new TypeUnifyTask(context).applyTypeUnificationRules(res.get(), finiteClosure);
} else } else
return x; // wenn nichts veraendert wurde wird x zurueckgegeben return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new)); }).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results);
System.out.println("Constraints for Generated Generics: " + " ???");
logFile.write("RES_FINAL: " + results.toString() + "\n");
logFile.flush();
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFile.flush();
} }
} catch (IOException e) { } catch (ClassNotFoundException e) {
System.err.println("kein LogFile");
} }
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()));
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons), context.placeholderRegistry())))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
} }
/** /**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
* *
@@ -661,82 +686,39 @@ public class JavaTXCompiler {
public final JavaClassRegistry classRegistry = new JavaClassRegistry(); public final JavaClassRegistry classRegistry = new JavaClassRegistry();
public record ClassEntry(File classFile, ClassOrInterface cif) {} private void parse(SourceFileContext tree, File sourceFile) throws IOException, java.lang.ClassNotFoundException {
public final Map<JavaClassName, ClassEntry> loadedClasses = new HashMap<>();
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
if (sourceFiles.containsKey(sourceFile)) return sourceFiles.get(sourceFile);
SourceFileContext tree = JavaTXParser.parse(sourceFile);
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName()); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
var classes = new ArrayList<ClassOrInterface>(); var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile("", classes, generator.imports); var sf = new SourceFile("", classes, generator.imports);
addSourceFile(sourceFile, sf); addSourceFile(sourceFile, sf);
generator.convert(classes, tree, environment.packageCrawler); generator.convert(classes, tree, environment.packageCrawler);
sf.setPackageName(generator.pkgName); sf.setPackageName(generator.pkgName);
sf.imports.addAll(generator.imports); sf.imports.addAll(generator.imports);
return sf;
}
/**
* When an import tries to import a JavaTX class it first looks it up in the cache and
* if it doesn't exist it's going to compile it and add it to the source files list
* @param name
*/
public ClassOrInterface loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
if (file != null) {
if (loadedClasses.containsKey(name)) return loadedClasses.get(name).cif();
try {
var tree = JavaTXParser.parse(file);
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
environment.addClassesToRegistry(classRegistry, tree, file, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), file.getName());
var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile("", classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
sf.setPackageName(generator.pkgName);
var classFiles = generateBytecode(file);
sf.setGenerated();
writeClassFile(classFiles, outputPath != null ? outputPath : new File("."), false);
var clazz = classLoader.loadClass(name.toString());
var classOrInterface = ASTFactory.createClass(clazz);
loadedClasses.put(name, new ClassEntry(new File(outputPath, clazz.getName() + ".class"), classOrInterface));
return classOrInterface;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return null;
}
public File findFileForClass(JavaClassName name) {
var packageName = name.getPackageName();
var className = name.getClassName().split("\\.")[0];
for (var cp : classPath) {
var file = new File(cp, packageName.replaceAll("\\.", "/") + "/" + className + ".jav");
if (file.exists()) return file;
}
return null;
} }
public void generateBytecode() throws ClassNotFoundException, IOException { public void generateBytecode() throws ClassNotFoundException, IOException {
for (var file : sourceFiles.keySet()) { if (inferTogether) {
var sf = sourceFiles.get(file); var files = sourceFiles.keySet().stream().toList();
if (sf.isGenerated()) continue; var typeinferenceResult = this.typeInference(files);
var classes = generateBytecode(file); for (var file : files) {
sf.setGenerated(); var sf = sourceFiles.get(file);
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null); if (sf.isGenerated()) continue;
var classes = generateBytecode(sf, typeinferenceResult);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
} else {
for (var file : sourceFiles.keySet()) {
var sf = sourceFiles.get(file);
if (sf.isGenerated()) continue;
var classes = generateBytecode(file);
sf.setGenerated();
writeClassFile(classes, outputPath == null ? file.getParentFile() : outputPath, outputPath == null);
}
} }
} }
/**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
* @return
*/
public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException { public Map<JavaClassName, byte[]> generateBytecode(File sourceFile) throws ClassNotFoundException, IOException {
var sf = sourceFiles.get(sourceFile); var sf = sourceFiles.get(sourceFile);
if (sf.isGenerated()) return null; if (sf.isGenerated()) return null;
@@ -778,12 +760,12 @@ public class JavaTXCompiler {
var codegen = new Codegen(converter.convert(clazz), this, converter); var codegen = new Codegen(converter.convert(clazz), this, converter);
var code = codegen.generate(); var code = codegen.generate();
generatedClasses.put(clazz.getClassName(), code); generatedClasses.put(clazz.getClassName(), code);
converter.auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source);
});
} }
generatedGenerics.put(sf, converter.javaGenerics()); generatedGenerics.put(sf, converter.javaGenerics());
converter.generateFunNTypes(); converter.generateFunNTypes();
auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source);
});
return generatedClasses; return generatedClasses;
} }
@@ -791,15 +773,15 @@ public class JavaTXCompiler {
FileOutputStream output; FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) { for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name); byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ..."); defaultLogger.info("generating " + name + ".class file ...");
var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile(); var subPath = preserveHierarchy ? path : Path.of(path.toString(), name.getPackageName().split("\\.")).toFile();
File outputFile = new File(subPath, name.getClassName() + ".class"); File outputFile = new File(subPath, name.getClassName() + ".class");
outputFile.getAbsoluteFile().getParentFile().mkdirs(); outputFile.getAbsoluteFile().getParentFile().mkdirs();
System.out.println(outputFile); defaultLogger.info(outputFile.toString());
output = new FileOutputStream(outputFile); output = new FileOutputStream(outputFile);
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
System.out.println(name + ".class file generated"); defaultLogger.success(name + ".class file generated");
} }
} }
@@ -0,0 +1,31 @@
package de.dhbwstuttgart.core;
import de.dhbwstuttgart.server.SocketServer;
public class JavaTXServer {
public static boolean isRunning = false;
final SocketServer socketServer;
public JavaTXServer(int port) {
this.socketServer = new SocketServer(port);
}
public void listen() {
isRunning = true;
socketServer.start();
}
public void forceStop() {
try {
socketServer.stop();
}
catch (InterruptedException exception) {
System.err.println("Interrupted socketServer: " + exception);
}
isRunning = false;
}
}
@@ -1,13 +0,0 @@
package de.dhbwstuttgart.environment;
public class ByteArrayClassLoader extends ClassLoader implements IByteArrayClassLoader {
@Override
public Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError {
return defineClass(name, code, i, length);
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
}
@@ -8,6 +8,7 @@ import java.util.*;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@@ -30,7 +31,7 @@ public class CompilationEnvironment {
public final PackageCrawler packageCrawler; public final PackageCrawler packageCrawler;
/** /**
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthlt automatisch die Java Standard Library * Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library
* *
* @param sourceFiles die zu kompilierenden Dateien * @param sourceFiles die zu kompilierenden Dateien
*/ */
@@ -87,6 +88,8 @@ public class CompilationEnvironment {
if (files != null) if (files != null)
for (File classFile : files) { for (File classFile : files) {
String className = classFile.getName().substring(0, classFile.getName().length() - 6); String className = classFile.getName().substring(0, classFile.getName().length() - 6);
// Don't load class if its defined in the input
if (compiler.input.contains(new JavaClassName(className))) continue;
if (className.matches("Fun\\d+\\$\\$.*")) if (className.matches("Fun\\d+\\$\\$.*"))
continue; continue;
var name = packageName; var name = packageName;
@@ -16,7 +16,7 @@ public class DirectoryClassLoader extends URLClassLoader implements IByteArrayCl
// } // }
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) { public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent()); super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent);
} }
private static URL[] generateURLArray(URL url) { private static URL[] generateURLArray(URL url) {
@@ -6,18 +6,22 @@ import java.nio.file.Path;
public interface IByteArrayClassLoader { public interface IByteArrayClassLoader {
Class loadClass(String path) throws ClassNotFoundException; Class<?> loadClass(String path) throws ClassNotFoundException;
default Class loadClass(byte[] code) { default Class<?> loadClass(byte[] code) {
return this._defineClass(null, code, 0, code.length); return this.loadClass(null, code);
} }
default Class loadClass(Path path) throws IOException { default Class<?> loadClass(String name, byte[] code) {
return this._defineClass(name, code, 0, code.length);
}
default Class<?> loadClass(Path path) throws IOException {
var code = Files.readAllBytes(path); var code = Files.readAllBytes(path);
return this._defineClass(null, code, 0, code.length); return this._defineClass(null, code, 0, code.length);
} }
public Class<?> findClass(String name) throws ClassNotFoundException; public Class<?> findClass(String name) throws ClassNotFoundException;
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError; Class<?> _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
} }
@@ -0,0 +1,11 @@
package de.dhbwstuttgart.exceptions;
/**
* Eine Runtime Exception, die für den Fall genutzt wird, dass eine Unifikation abgebrochen wird.
* Durch das Werfen einer Exception können Abbrüche auch aus Methodenaufrufen heraus
* geprüft werden, da zuvor nur ein return X; stattfinden würde.
*/
public class UnifyCancelException extends RuntimeException {
}
@@ -0,0 +1,120 @@
package de.dhbwstuttgart.languageServerInterface;
import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.tree.TargetStructure;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
*/
public class LanguageServerInterface {
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
NameGenerator.resetTo(resetNamesTo);
return getResultSetAndAbstractSyntax(path);
}
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
NameGenerator.resetTo(resetNamesTo);
return getAST(path);
}
/**
* returns the ResultSets, GenericResultSet and the AST
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
*
* @param pathAsString the URI of the File. See Example.
*/
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString){
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
try {
var uri = new URI(pathAsString);
var path = Path.of(uri);
var file = path.toFile();
Files.createDirectories(path.getParent().resolve("out"));
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile(), false);
var parsedSource = compiler.sourceFiles.get(file);
var tiResults = compiler.typeInference(file);
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
Files.createDirectories(path.getParent().resolve("out"));
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* returns the AST without calculating the result
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
*
* @param path the URI of the File. See Example.
* @throws IOException
* @throws ClassNotFoundException
* @throws URISyntaxException
*/
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
URI uri = new URI(path);
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
String stringPathWithoutName = "";
for (String i : pathWithoutName) {
stringPathWithoutName += "/" + i;
}
try {
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
} catch (Exception e) {
}
try {
(new File(stringPathWithoutName + "/out")).mkdirs();
} catch (Exception e) {
}
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
System.setOut(System.out);
return test;
}
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
var file = Path.of(filePath, filename).toFile();
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile(), false);
return compiler.sourceFiles.get(file);
}
}
@@ -0,0 +1,40 @@
package de.dhbwstuttgart.languageServerInterface;
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.List;
public class ParserInterface {
public List<ParserError> getParseErrors(String input){
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
CharStream charStream = CharStreams.fromString(input);
Java17Lexer lexer = new Java17Lexer(charStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Java17Parser parser = new Java17Parser(tokens);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
ParseTree tree = parser.sourceFile();
ParseTreeWalker walker = new ParseTreeWalker();
Java17ParserBaseListener listener = new Java17ParserBaseListener();
walker.walk(listener, tree);
return errorListener.getErrorMessages();
}
}
@@ -0,0 +1,47 @@
package de.dhbwstuttgart.languageServerInterface.model;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.dfa.DFA;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
public class CustomParserErrorHandler implements ANTLRErrorListener {
private final List<ParserError> errorMessages = new ArrayList<>();
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
int endCharPosition = charPositionInLine;
if (offendingSymbol instanceof Token) {
Token offendingToken = (Token) offendingSymbol;
endCharPosition = charPositionInLine + offendingToken.getText().length();
}
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
errorMessages.add(parserError);
}
@Override
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
}
@Override
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
}
@Override
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
}
public List<ParserError> getErrorMessages() {
return errorMessages;
}
}
@@ -0,0 +1,31 @@
package de.dhbwstuttgart.languageServerInterface.model;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LanguageServerTransferObject {
List<ResultSet> resultSets;
SourceFile Ast;
String printedAst;
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
this.resultSets = resultSets;
this.Ast = Ast;
this.printedAst = printedAst;
this.generatedGenerics = generatedGenerics;
}
public List<ResultSet> getResultSets() {return resultSets;}
public SourceFile getAst() {return Ast;}
public String getPrintedAst() {return printedAst;}
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
}
@@ -0,0 +1,48 @@
package de.dhbwstuttgart.languageServerInterface.model;
public class ParserError {
private int line;
private int charPositionInLine;
private int endCharPosition;
String msg;
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
this.line = line;
this.charPositionInLine = charPositionInLine;
this. endCharPosition = endCharPosition;
this.msg = msg;
}
public int getEndCharPosition() {
return endCharPosition;
}
public void setEndCharPosition(int endCharPosition) {
this.endCharPosition = endCharPosition;
}
public void setCharPositionInLine(int charPositionInLine) {
this.charPositionInLine = charPositionInLine;
}
public void setLine(int line) {
this.line = line;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCharPositionInLine() {
return charPositionInLine;
}
public int getLine() {
return line;
}
public String getMsg() {
return msg;
}
}
@@ -0,0 +1,20 @@
package de.dhbwstuttgart.languageServerInterface.model;
import com.google.common.reflect.TypeResolver;
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
public class ResultSetListener implements UnifyResultListener {
TypeResolver typeResolver;
public ResultSetListener(TypeResolver typeResolver){
this.typeResolver = typeResolver;
}
@Override
public void onNewTypeResultFound(UnifyResultEvent evt) {
}
}
@@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.util.Logger;
import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.CommonTokenStream;
@@ -17,6 +18,9 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class JavaTXParser { public class JavaTXParser {
public static Logger logger = new Logger("Parser");
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException { public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
InputStream stream = new FileInputStream(source); InputStream stream = new FileInputStream(source);
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream); // DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
@@ -1,4 +1,25 @@
package de.dhbwstuttgart.parser; package de.dhbwstuttgart.parser;
public record SourceLoc(String file, int line) { import de.dhbwstuttgart.server.packet.dataContainers.ISerializableData;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
public record SourceLoc(String file, int line) implements ISerializableData {
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
var serialized = new SerialMap();
serialized.put("file", file);
serialized.put("line", line);
return serialized;
}
public static SourceLoc fromSerial(SerialMap data) {
return new SourceLoc(
data.getValue("file").getOf(String.class),
data.getValue("line").getOf(Integer.class)
);
}
} }
@@ -12,6 +12,7 @@ import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.model.*; import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.*; import java.util.*;
@@ -26,16 +27,21 @@ public class FCGenerator {
* *
* @param availableClasses - Alle geparsten Klassen * @param availableClasses - Alle geparsten Klassen
*/ */
public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException { public static Set<UnifyPair> toUnifyFC(JavaTXCompiler compiler, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(compiler, t)).collect(Collectors.toSet()); return toFC(
availableClasses,
classLoader,
placeholderRegistry
).stream().map(t -> UnifyTypeFactory.convert(compiler, t, placeholderRegistry))
.collect(Collectors.toSet());
} }
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException { public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader, PlaceholderRegistry placeholderRegistry) throws ClassNotFoundException {
HashSet<Pair> pairs = new HashSet<>(); HashSet<Pair> pairs = new HashSet<>();
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden. //PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
for(ClassOrInterface cly : availableClasses){ for(ClassOrInterface cly : availableClasses){
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader); List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader, placeholderRegistry);
pairs.addAll(newPairs); pairs.addAll(newPairs);
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC //For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
@@ -75,8 +81,13 @@ public class FCGenerator {
* @param forType * @param forType
* @return * @return
*/ */
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException { private static List<Pair> getSuperTypes(
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader); ClassOrInterface forType,
Collection<ClassOrInterface> availableClasses,
ClassLoader classLoader,
PlaceholderRegistry placeholderRegistry
) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader, placeholderRegistry);
} }
/** /**
@@ -87,8 +98,13 @@ public class FCGenerator {
* @return * @return
* @throws ClassNotFoundException * @throws ClassNotFoundException
*/ */
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, private static List<Pair> getSuperTypes(
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, ClassLoader classLoader) throws ClassNotFoundException { ClassOrInterface forType,
Collection<ClassOrInterface> availableClasses,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs,
ClassLoader classLoader,
PlaceholderRegistry placeholderRegistry
) throws ClassNotFoundException {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
//Die GTVs, die in forType hinzukommen: //Die GTVs, die in forType hinzukommen:
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
@@ -147,7 +163,7 @@ public class FCGenerator {
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){ if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER)); superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{ }else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader); superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader, placeholderRegistry);
} }
retList.add(ret); retList.add(ret);
@@ -158,7 +174,8 @@ public class FCGenerator {
} }
/** /**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus. * Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf der direkten Argumentebene.
* Hier sind keine Wildcards zulässig
*/ */
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{ private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
@@ -172,7 +189,7 @@ public class FCGenerator {
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
params.add(param.acceptTV(this)); params.add(param.acceptTV(new TypeExchangerInner(gtvs)));
} }
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken()); RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret; return ret;
@@ -201,4 +218,51 @@ public class FCGenerator {
} }
} }
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf den Argumenten der Argumente.
* Hier sind Wildcards zulässig
*/
private static class TypeExchangerInner implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchangerInner(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
this.gtvs = gtvs;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
params.add(param.acceptTV(this));
}
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
return superWildcardType;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
return extendsWildcardType;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
return gtvs.get(genericRefType.getParsedName());
}
}
} }
@@ -1,5 +1,6 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator; package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.JavaTXParser;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -14,6 +15,8 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@@ -101,7 +104,6 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.stringtemplate.v4.ST;
public class StatementGenerator { public class StatementGenerator {
@@ -125,7 +127,7 @@ public class StatementGenerator {
this.superClass = superType; this.superClass = superType;
} }
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) { public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext, boolean methodparameters) {
List<Pattern> ret = new ArrayList<>(); List<Pattern> ret = new ArrayList<>();
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>(); List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
if (Objects.isNull(formalParameterListContext)) if (Objects.isNull(formalParameterListContext))
@@ -147,7 +149,9 @@ public class StatementGenerator {
if (fp.typeType() != null) { if (fp.typeType() != null) {
type = TypeGenerator.convert(fp.typeType(), reg, generics); type = TypeGenerator.convert(fp.typeType(), reg, generics);
} else { } else {
type = TypePlaceholder.fresh(fp.getStart()); type = methodparameters?
TypePlaceholder.fresh(fp.getStart(), 1, false)
: TypePlaceholder.fresh(fp.getStart(), 1, false);
} }
ret.add(new FormalParameter(paramName, type, fp.getStart())); ret.add(new FormalParameter(paramName, type, fp.getStart()));
localVars.put(paramName, type); localVars.put(paramName, type);
@@ -256,7 +260,7 @@ public class StatementGenerator {
ret.setStatement(); ret.setStatement();
return ret; return ret;
default: default:
System.out.println(stmt.getClass()); JavaTXParser.logger.info(stmt.getClass());
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@@ -439,6 +443,7 @@ public class StatementGenerator {
} }
private Pattern convert(PatternContext pattern) { private Pattern convert(PatternContext pattern) {
return switch (pattern) { return switch (pattern) {
case PPatternContext pPattern -> { case PPatternContext pPattern -> {
yield convert(pPattern.primaryPattern()); yield convert(pPattern.primaryPattern());
@@ -453,30 +458,36 @@ public class StatementGenerator {
} }
private FormalParameter convert(PrimaryPatternContext pPattern) { private FormalParameter convert(PrimaryPatternContext pPattern) {
switch (pPattern) { switch (pPattern) {
case TPatternContext tPattern: case TPatternContext tPattern:
TypePatternContext typePattern = tPattern.typePattern(); TypePatternContext typePattern = tPattern.typePattern();
var text = typePattern.identifier().getText(); var text = typePattern.identifier().getText();
var type = TypeGenerator.convert(typePattern.typeType(), reg, generics); var type = typePattern.typeType() == null ? TypePlaceholder.fresh(pPattern.getStart()) : TypeGenerator.convert(typePattern.typeType(), reg, generics);
localVars.put(text, type); localVars.put(text, type);
return new FormalParameter(text, type, typePattern.getStart()); return new FormalParameter(text, type, typePattern.getStart());
case RPatternContext rPattern: case RPatternContext rPattern:
RecordPatternContext recordPattern = rPattern.recordPattern(); RecordPatternContext recordPattern = rPattern.recordPattern();
return convert(recordPattern); return convert(recordPattern);
default: case Java17Parser.LPatternContext patternContext: return new LiteralPattern(TypePlaceholder.fresh(patternContext.start), convert(patternContext.literal().get(0)), patternContext.start);
throw new NotImplementedException();
default:
throw new NotImplementedException();
} }
} }
private RecordPattern convert(RecordPatternContext recordPatternCtx) { private RecordPattern convert(RecordPatternContext recordPatternCtx) {
List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern(); var cpl = recordPatternCtx.recordStructurePattern().recordComponentPatternList();
List<PatternContext> subPatternCtx = cpl == null ? List.of() : cpl.pattern();
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList()); List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
IdentifierContext identifierCtx = recordPatternCtx.identifier(); IdentifierContext identifierCtx = recordPatternCtx.identifier();
var text = (identifierCtx != null) ? identifierCtx.getText() : null; var text = (identifierCtx != null) ? identifierCtx.getText() : null;
var type = TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics); //Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
var type = recordPatternCtx.typeType() == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
if (text != null) localVars.put(text, type); if (text != null) localVars.put(text, type);
return new RecordPattern(subPattern, text, type, recordPatternCtx.getStart()); var ret = new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
return ret;
} }
private Statement convert(Java17Parser.WhileloopContext stmt) { private Statement convert(Java17Parser.WhileloopContext stmt) {
@@ -583,7 +594,7 @@ public class StatementGenerator {
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
var fieldEntry = fields.get(name.getText()); var fieldEntry = fields.get(name.getText());
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart())); return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
} }
private Statement convert(Java17Parser.BreakstmtContext stmt) { private Statement convert(Java17Parser.BreakstmtContext stmt) {
@@ -697,7 +708,7 @@ public class StatementGenerator {
if (!Objects.isNull(expr.methodCall())) { if (!Objects.isNull(expr.methodCall())) {
return convert(expr.methodCall(), expr.expression(), offset); return convert(expr.methodCall(), expr.expression(), offset);
} else if (!Objects.isNull(expr.identifier())) { } else if (!Objects.isNull(expr.identifier())) {
return generateLocalOrFieldVarOrClassName(expr.getText(), offset); return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset);
} else { } else {
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite // Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
// generische Invokationen // generische Invokationen
@@ -779,57 +790,19 @@ public class StatementGenerator {
* @return * @return
*/ */
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) { private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
String[] parts = expression.split("\\."); // Check for localVar:
if (parts.length < 2) { if (localVars.get(expression) != null) {
// Check for localVar: return new LocalVar(expression, localVars.get(expression), offset);
if (localVars.get(expression) != null) { } else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
return new LocalVar(expression, localVars.get(expression), offset); // gleiche TPH bekommen
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
// gleiche TPH bekommen } else if (reg.contains(expression)) {
var field = fields.get(expression); return generateStaticClassName(expression, offset);
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
} else if (reg.contains(expression)) {
return generateStaticClassName(expression, offset);
} else {
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
localVars.put(expression, TypePlaceholder.fresh(offset));
return new LocalVar(expression, localVars.get(expression), offset);
}
}
return generateFieldVarOrClassname(expression, offset);
}
private Expression generateFieldVarOrClassname(String expression, Token offset) {
String[] parts = expression.split("\\.");
String whole = "";
Expression receiver = null;
for (String part : parts) {
whole += part;
// Check for Classname:
if (reg.contains(whole)) {
receiver = generateStaticClassName(whole, offset);
break;
}
whole += ".";
}
var fieldName = parts[parts.length - 1];
var isStatic = false;
if (parts.length < 2 || parts[0].contentEquals("this")) {
receiver = new This(offset);
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
} else if (parts[0].contentEquals("super")) {
receiver = new Super(TypePlaceholder.fresh(offset), offset);
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
receiver = generateLocalOrFieldVarOrClassName(part, offset);
} else { } else {
StaticClassName cname = (StaticClassName) receiver; // lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
var javaClassName = reg.getName(cname.getType().toString()); localVars.put(expression, TypePlaceholder.fresh(offset));
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier); return new LocalVar(expression, localVars.get(expression), offset);
} }
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
} }
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) { private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
@@ -865,10 +838,8 @@ public class StatementGenerator {
private Statement convert(AssignexpressionContext expr) { private Statement convert(AssignexpressionContext expr) {
switch (expr.bop.getText()) { switch (expr.bop.getText()) {
case "=": case "=":
ExpressionContext leftside = expr.expression(0); AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0)));
AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart()); return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
return ret;
case "+=": case "+=":
case "-=": case "-=":
case "*=": case "*=":
@@ -885,8 +856,8 @@ public class StatementGenerator {
} }
} }
private AssignLeftSide convert(String leftHandSide, Token start) { private AssignLeftSide convertAssignLHS(Expression expr) {
Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start); Expression leftSide = expr;
if (leftSide instanceof FieldVar) if (leftSide instanceof FieldVar)
return new AssignToField((FieldVar) leftSide); return new AssignToField((FieldVar) leftSide);
else if (leftSide instanceof LocalVar) else if (leftSide instanceof LocalVar)
@@ -1095,17 +1066,17 @@ public class StatementGenerator {
List<Pattern> parameterList = new ArrayList<>(); List<Pattern> parameterList = new ArrayList<>();
for (IdentifierContext identifier : lambdaParams.identifier()) { for (IdentifierContext identifier : lambdaParams.identifier()) {
Token offset = identifier.getStart(); Token offset = identifier.getStart();
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset)); parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset, 1, false), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) { } else if (lambdaParams.formalParameterList() != null) {
params = convert(lambdaParams.formalParameterList()); params = convert(lambdaParams.formalParameterList(), false);
// }else if( lambdaParams.inferredFormalParameterList != null){ // }else if( lambdaParams.inferredFormalParameterList != null){
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) { } else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
List<Pattern> parameterList = new ArrayList<>(); List<Pattern> parameterList = new ArrayList<>();
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) { for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
Token offset = param.getStart(); Token offset = param.getStart();
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset)); parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else { } else {
@@ -1129,9 +1100,9 @@ public class StatementGenerator {
block = lambdaGenerator.convert(expression.lambdaBody().block(), true); block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
} }
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
funNParams.add(TypePlaceholder.fresh(expression.getStart()));// ret-Type funNParams.add(TypePlaceholder.fresh(expression.getStart(), -1, false));// ret-Type
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen: params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
funNParams.add(TypePlaceholder.fresh(expression.getStart()))); funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false)));
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart()); RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
// RefType lambdaType = new // RefType lambdaType = new
// RefType(reg.getName("Fun"+params.getFormalparalist().size()), // RefType(reg.getName("Fun"+params.getFormalparalist().size()),
@@ -111,7 +111,7 @@ public class SyntaxTreeGenerator {
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
this.allmodifiers.put("sealed", 4096); this.allmodifiers.put("sealed", 4096);
this.allmodifiers.put("non-sealed", 8192); this.allmodifiers.put("non-sealed", 8192);
this.allmodifiers.put("default", 16384); this.allmodifiers.put("default", 0); // Doesn't exist
this.allmodifiers.put("strictfp", 32768); this.allmodifiers.put("strictfp", 32768);
this.compiler = compiler; this.compiler = compiler;
@@ -254,7 +254,10 @@ public class SyntaxTreeGenerator {
List<RefType> implementedInterfaces = new ArrayList<>(); List<RefType> implementedInterfaces = new ArrayList<>();
List<Pattern> constructorParameters = new ArrayList<>(); List<Pattern> constructorParameters = new ArrayList<>();
List<Statement> constructorStatements = new ArrayList<>(); List<Statement> constructorStatements = new ArrayList<>();
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
List<Java17Parser.RecordComponentContext> components = recordDeclaration.recordHeader().recordComponentList() != null ?
recordDeclaration.recordHeader().recordComponentList().recordComponent(): List.of();
for (RecordComponentContext component : components) {
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final"); int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
String fieldname = component.identifier().getText(); String fieldname = component.identifier().getText();
Token fieldoffset = component.getStart(); Token fieldoffset = component.getStart();
@@ -266,7 +269,7 @@ public class SyntaxTreeGenerator {
} }
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset)); fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset)); constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset); FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset)); constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
Statement returnStatement = new Return(fieldvar, offset); Statement returnStatement = new Return(fieldvar, offset);
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset)); methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
@@ -390,12 +393,12 @@ public class SyntaxTreeGenerator {
if (!Objects.isNull(ctx.EXTENDS())) { if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics)); extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
} }
List<RefType> permittedSubtypes = new ArrayList<>(); List<RefType> permittedSubtypes = null;
// Ist Bit für 'sealed'-Modifier gesetzt // Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) { if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) { if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration') // permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics)); permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else { } else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt // falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration"); throw new NotImplementedException("Invalid sealed class declaration");
@@ -432,7 +435,7 @@ public class SyntaxTreeGenerator {
} }
} }
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList()); ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList(), true);
MethodBodyContext body = bodydeclaration.methodBody(); MethodBodyContext body = bodydeclaration.methodBody();
Block block = null; Block block = null;
if (!(body instanceof EmptymethodContext)) { if (!(body instanceof EmptymethodContext)) {
@@ -529,7 +532,7 @@ public class SyntaxTreeGenerator {
RefTypeOrTPHOrWildcardOrGeneric retType; RefTypeOrTPHOrWildcardOrGeneric retType;
if (Objects.isNull(header.refType())) { if (Objects.isNull(header.refType())) {
retType = TypePlaceholder.fresh(header.getStart()); retType = TypePlaceholder.fresh(header.getStart(), -1, false);
} else { } else {
if (header.refType() instanceof RefType2Context reftype) { if (header.refType() instanceof RefType2Context reftype) {
retType = TypeGenerator.convert(reftype.typeType(), reg, generics); retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
@@ -538,7 +541,7 @@ public class SyntaxTreeGenerator {
} }
} }
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList()); ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList(), true);
MethodBodyContext body = methoddeclaration.methodBody(); MethodBodyContext body = methoddeclaration.methodBody();
Block block = null; Block block = null;
if (body instanceof EmptymethodContext emptymethod) { if (body instanceof EmptymethodContext emptymethod) {
@@ -578,7 +581,7 @@ public class SyntaxTreeGenerator {
} }
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics); RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>()); StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList()); ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList(), true);
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass); Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart()); return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
} }
@@ -591,7 +594,7 @@ public class SyntaxTreeGenerator {
} else { } else {
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die // PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
// Modifier zu bekommen // Modifier zu bekommen
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart()); fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart(), -1, false);
} }
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) { for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
String fieldName = varDecl.variableDeclaratorId().getText(); String fieldName = varDecl.variableDeclaratorId().getText();
@@ -74,7 +74,7 @@ public class TypeGenerator {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen } else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
// System.out.println(unannTypeContext.getText()); // JavaTXParser.logger.info(unannTypeContext.getText());
throw new NotImplementedException(); throw new NotImplementedException();
} }
/* /*
@@ -168,7 +168,7 @@ public class TypeGenerator {
if (generics.contains(name)) { if (generics.contains(name)) {
return new GenericRefType(name, offset); return new GenericRefType(name, offset);
} else { } else {
Pattern p = Pattern.compile("Fun(\\d+)[$][$]"); Pattern p = Pattern.compile("Fun(Void|VoidImpl|Wrapper)?(\\d+)[$][$]"); // TODO Regex shenanigans
Matcher m = p.matcher(name); Matcher m = p.matcher(name);
if (m.matches()) {// es ist FunN$$-Type if (m.matches()) {// es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset); return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
@@ -140,8 +140,7 @@ public class GatherNames {
if (importDeclCtx.MUL() == null) { if (importDeclCtx.MUL() == null) {
var name = importDeclCtx.qualifiedName().getText(); var name = importDeclCtx.qualifiedName().getText();
var className = new JavaClassName(name); var className = new JavaClassName(name);
var clazz = compiler.loadJavaTXClass(className); if (compiler.input.contains(className)) {
if (clazz != null) {
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name)); ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
} else { } else {
Class<?> cl = compiler.getClassLoader().loadClass(name); Class<?> cl = compiler.getClassLoader().loadClass(name);
@@ -41,7 +41,7 @@ public class JavaClassName {
} }
/** /**
* Gibt von einem Klassennamen nur den Namen der Klasse zurck * Gibt von einem Klassennamen nur den Namen der Klasse zurück
* Beispiel: * Beispiel:
* java.lang.Object wird zu: Object * java.lang.Object wird zu: Object
*/ */
@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import java.util.*; import java.util.*;
/** /**
* Speichert die Klassen fr einen bestimmten Projektscope * Speichert die Klassen für einen bestimmten Projektscope
*/ */
public class JavaClassRegistry { public class JavaClassRegistry{
final Map<JavaClassName, Integer> existingClasses = new HashMap<>(); final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
public JavaClassRegistry(Map<String, Integer> initialNames) { public JavaClassRegistry(Map<String, Integer> initialNames) {
@@ -22,6 +22,10 @@ public class JavaClassRegistry {
} }
} }
public Set<JavaClassName> getAllClassNames(){
return existingClasses.keySet();
}
public void addName(String className, int numberOfGenerics) { public void addName(String className, int numberOfGenerics) {
existingClasses.put(new JavaClassName(className), numberOfGenerics); existingClasses.put(new JavaClassName(className), numberOfGenerics);
} }
@@ -60,6 +64,6 @@ public class JavaClassRegistry {
} }
public int getNumberOfGenerics(String name) { public int getNumberOfGenerics(String name) {
return existingClasses.get(new JavaClassName(name)); return existingClasses.getOrDefault(new JavaClassName(name), 0);
} }
} }
@@ -0,0 +1,41 @@
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
}
}
@@ -0,0 +1,202 @@
package de.dhbwstuttgart.server;
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.IServerToClientPacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.server.packet.UnifyRequestPacket;
import de.dhbwstuttgart.server.packet.UnifyResultPacket;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.util.Logger;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
/**
* The Client-side of the websocket
*/
public class SocketClient extends WebSocketClient {
public static Logger logger = new Logger("SocketClient");
/**
* The singleton object
*/
private static SocketClient socketClient = null;
/**
* List of futures that are still waiting to be fulfilled
*/
private final Map<String, SocketFuture<?>> responseFutures = new HashMap<>();
private SocketClient(String url) {
super(
URI.create(url), // target url
//SocketServer.perMessageDeflateDraft, // enable compression
Map.of( // headers
"packetProtocolVersion", SocketServer.packetProtocolVersion
)
);
// make sure the url is in a valid format
final String regex = "^wss?://(\\w+(\\.\\w+)?)*:(\\d+)$";
final Matcher matcher = Pattern.compile(regex).matcher(url);
if (!matcher.find()) {
throw new RuntimeException("Provided string \"" + url + "\" is not a valid server URL! Use pattern ws(s?)://<host.name>:<port>");
}
try {
// wait for the connection to be set up
this.connectBlocking();
// make sure the connection has been established successfully
if (this.getReadyState() != ReadyState.OPEN) {
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
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
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);
client.send(json);
} catch (Exception exception) {
logger.exception(exception);
throw new RuntimeException("Exception occurred in server connection: ", exception);
}
return future;
}
/**
* 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
*/
protected void handleReceivedPacket(IPacket packet) {
if (!(packet instanceof IServerToClientPacket serverToClientPacket)) {
System.err.println("Received package of invalid type + " + packet.getClass().getName());
this.close();
return;
}
serverToClientPacket.onHandle(this.getConnection(), this);
}
/**
* Complete a registered future, so it can be handled by whoever executed the creator task
*
* @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
public void onOpen(ServerHandshake handshakedata) {
logger.success("Connected to server with status " + handshakedata.getHttpStatus());
}
@Override
public void onMessage(String message) {
// logger.info("received: " + message);
IPacket packet = PacketContainer.deserialize(message);
this.handleReceivedPacket(packet);
}
@Override
public void onClose(int code, String reason, boolean remote) {
logger.info(
"Disconnected from server " +
"with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by remote: " + remote + ")"
);
if (!this.responseFutures.isEmpty()) {
throw new RuntimeException("Server closed before all required tasks were answered");
}
}
@Override
public void onError(Exception e) {
logger.exception(e);
throw new RuntimeException(e);
}
}
@@ -0,0 +1,48 @@
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;
}
}
@@ -0,0 +1,235 @@
package de.dhbwstuttgart.server;
import com.fasterxml.jackson.core.JsonProcessingException;
import de.dhbwstuttgart.server.packet.ErrorPacket;
import de.dhbwstuttgart.server.packet.IClientToServerPacket;
import de.dhbwstuttgart.server.packet.IPacket;
import de.dhbwstuttgart.server.packet.MessagePacket;
import de.dhbwstuttgart.server.packet.PacketContainer;
import de.dhbwstuttgart.util.Logger;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.java_websocket.WebSocket;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class SocketServer extends WebSocketServer {
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.
* This will prevent errors when the server version and client version do not match.
*/
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<>());
// create an executor for scheduling timeouts
private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
public SocketServer(int port) {
super(new InetSocketAddress(port));
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
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
String ppv = clientHandshake.getFieldValue("packetProtocolVersion");
if (!ppv.equals(packetProtocolVersion)) {
this.sendError(webSocket,
"Mismatch in packet protocol version! Client (you): \"" + ppv + "\" and Server (me): \"" + packetProtocolVersion + "\"",
true
);
webSocket.close(1);
return;
}
SocketData socketData = new SocketData(webSocket);
logger.info("New connection: " + socketData.id + " (with ppv " + ppv + ")");
try {
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
final int secondsUntilTimeout = 10;
timeoutExecutor.schedule(() -> {
if (webSocket.<SocketData>getAttachment().totalTasks.get() > 0 || !webSocket.isOpen()) {
return;
}
sendMessage(webSocket, "No task received after " + secondsUntilTimeout + " seconds. Closing connection...");
webSocket.close();
},
secondsUntilTimeout,
TimeUnit.SECONDS
);
// and finally, when your program wants to exit
} catch (Exception e) {
logger.exception(e);
webSocket.close(1, e.getMessage());
}
}
@Override
public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
SocketData socketData = webSocket.getAttachment();
logger.info("Connection closed: " + socketData.id);
logger.info(
"Disconnected client " + socketData.id + " " +
"with code " + code + " " +
(reason.isEmpty() ? "" : "and reason " + reason + " ") +
"(closed by client: " + remote + ")"
);
}
@Override
public void onMessage(WebSocket webSocket, String s) {
// logger.info("Received: " + s.substring(0, 50));
IPacket reconstructedPacket = PacketContainer.deserialize(s);
try {
this.onPacketReceived(webSocket, reconstructedPacket);
} catch (JsonProcessingException e) {
logger.exception(e);
this.log(webSocket, "Error on processing incoming package: " + e.getMessage());
}
}
@Override
public void onError(WebSocket webSocket, Exception e) {
if (webSocket != null) {
log(webSocket, e.getMessage());
webSocket.close();
}
logger.exception(e);
}
@Override
public void onStart() {
logger.success("Websocket server started on port " + this.getPort());
}
/**
* A shorthand method for sending informational messages to the client
*/
public void sendMessage(WebSocket webSocket, String text) {
try {
MessagePacket message = MessagePacket.create(text);
webSocket.send(PacketContainer.serialize(message));
} catch (Exception e) {
System.err.println("Failed to send message: " + text);
logger.exception(e);
}
}
/**
* A shorthand method for sending error messages to the client
*/
public void sendError(WebSocket webSocket, String text, boolean isFatal) {
try {
ErrorPacket error = ErrorPacket.create(text, isFatal);
webSocket.send(PacketContainer.serialize(error));
} catch (Exception e) {
logger.exception(e);
log(webSocket, "Failed to send error: " + text);
}
}
/**
* The server-side implementation on how to handle certain packets when received
*/
private void onPacketReceived(WebSocket webSocket, IPacket packet) throws JsonProcessingException {
SocketData socketData = webSocket.getAttachment();
// limit the number of tasks per connection
if (socketData.totalTasks.get() >= maxTasksPerSession) {
sendError(webSocket, "Exceeded the maximum amount of " + maxTasksPerSession + " tasks per session", true);
webSocket.close();
return;
}
// only allow packets that are meant to be handled by the server
if (!(packet instanceof IClientToServerPacket<?> clientToServerPacket)) {
sendMessage(webSocket, "The package of type " + packet.getClass().getName() + " is not handled by the server!");
return;
}
// update the socket data
socketData.unhandledTasks.incrementAndGet();
socketData.totalTasks.incrementAndGet();
// add the packet to the queue so it can be started by the worker
CompletableFuture.runAsync(() -> {
clientToServerPacket.onHandle(webSocket, this);
int remainingUnhandledTasks = socketData.unhandledTasks.decrementAndGet();
if (socketData.closeIfNoTasksLeft) {
// if the websocket has 0 unhandled Tasks, close the connection
if (remainingUnhandledTasks <= 0) {
sendMessage(webSocket, "All requested tasks finished! Closing connection...");
webSocket.close();
}
}
}, taskExecutor);
}
public void log(WebSocket webSocket, String msg) {
String socketId = (webSocket == null) ? "???" : webSocket.<SocketData>getAttachment().id;
logger.info("[" + socketId + "] " + msg);
}
/**
* The data that is associated server-side with any connected client.
* This makes it possible to store information that can be mapped to any existing connection.
*/
public static class SocketData {
public final String id;
public final AtomicInteger unhandledTasks = new AtomicInteger(0);
public final AtomicInteger totalTasks = new AtomicInteger(0);
public boolean closeIfNoTasksLeft = false;
public SocketData(WebSocket webSocket) {
this.id = UUID.randomUUID().toString();
webSocket.setAttachment(this);
}
}
}
@@ -0,0 +1,35 @@
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 de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialUUID;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import org.java_websocket.WebSocket;
public class DebugPacket implements IClientToServerPacket.Void, IServerToClientPacket {
public SerialUUID a1;
public SerialUUID a2;
public SerialMap b1;
public SerialMap b2;
public SerialList<? extends ISerialNode> c1;
public SerialList<? extends ISerialNode> c2;
public SerialValue<?> d1;
public SerialValue<?> d2;
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}
@@ -0,0 +1,36 @@
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;
/**
* A packet to send simple error messages between the client and the server
*/
public class ErrorPacket implements IServerToClientPacket {
/**
* The error endpoint for messages from the server that should be logged out as errors and possibly abort the process
*/
public String error;
public boolean isFatal;
@JsonIgnore
public static ErrorPacket create(String error, boolean isFatal) {
ErrorPacket packet = new ErrorPacket();
packet.error = error;
packet.isFatal = isFatal;
return packet;
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.exception(new RuntimeException(this.error));
if (this.isFatal) {
socketClient.close(1, "Received fatal error from server");
}
}
}
@@ -0,0 +1,26 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketFuture;
import de.dhbwstuttgart.server.SocketServer;
import org.java_websocket.WebSocket;
/**
* 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
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> {}
}
@@ -0,0 +1,12 @@
package de.dhbwstuttgart.server.packet;
/**
* The shared interface for all packet of the client-server connection.
* A packet must always:
* - Have a default / no-parameter constructor
* - Have only serializable public properties (or disable them via jackson annotations)
*
*/
public interface IPacket {
}
@@ -0,0 +1,12 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import org.java_websocket.WebSocket;
public interface IServerToClientPacket extends IPacket {
@JsonIgnore
void onHandle(WebSocket webSocket, SocketClient socketClient);
}
@@ -0,0 +1,35 @@
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;
/**
* 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 {
/**
* If available, the error that caused this package to appear
*/
public String error = "<unknown error>";
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.error("InvalidPacket: " + this.error);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, "InvalidPacket: " + this.error);
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}
@@ -0,0 +1,40 @@
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;
/**
* A packet to send simple informational messages between the client and the server
*/
public class MessagePacket implements IClientToServerPacket.Void, IServerToClientPacket {
/**
* The informational message from the server that should be logged out outputted
*/
public String message;
@JsonIgnore
public static MessagePacket create(String message) {
MessagePacket packet = new MessagePacket();
packet.message = message;
return packet;
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.info("SocketMessage: " + this.message);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.log(webSocket, this.message);
}
@JsonIgnore
public SocketFuture<IServerToClientPacket> getFuture() {
return SocketFuture.completedFuture();
}
}
@@ -0,0 +1,98 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.dhbwstuttgart.util.Logger;
/**
* A wrapper for the packet to ensure correct serialization/deserialization and make it possible to detect the matching
* packet type for deserialization.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PacketContainer {
// The jackson serializer / deserializer tool
private static final ObjectMapper objectMapper = new ObjectMapper();
/*
* The available packet types. The one type that is represented in the JSON should always be the ONLY non-null value.
* They have to be public (for the moment) to let jackson fill them in while deserializing
*/
public ErrorPacket errorPacket = null;
public MessagePacket messagePacket = null;
public InvalidPacket invalidPacket = null;
public UnifyRequestPacket unifyRequestPacket = null;
public UnifyResultPacket unifyResultPacket = null;
public DebugPacket debugPacket = null;
public SetAutoclosePacket setAutoclosePacket = null;
/**
* Generate the JSON string for the given packet
*
* @param packet The packet to serialize
* @return The JSON representation of the packet
*/
public static String serialize(IPacket packet) throws JsonProcessingException {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
PacketContainer container = new PacketContainer();
if (packet instanceof ErrorPacket)
container.errorPacket = (ErrorPacket) packet;
else if (packet instanceof MessagePacket)
container.messagePacket = (MessagePacket) packet;
else if (packet instanceof UnifyRequestPacket)
container.unifyRequestPacket = (UnifyRequestPacket) packet;
else if (packet instanceof UnifyResultPacket)
container.unifyResultPacket = (UnifyResultPacket) packet;
else if (packet instanceof DebugPacket)
container.debugPacket = (DebugPacket) packet;
else if (packet instanceof SetAutoclosePacket)
container.setAutoclosePacket = (SetAutoclosePacket) packet;
// 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);
}
/**
* Use the JSON string to generate the matching packet object
*
* @param json The serialized representation of a packet container
* @return The deserialized Packet object
*/
public static IPacket deserialize(String json) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
try {
PacketContainer container = objectMapper.readValue(json, PacketContainer.class);
if (container.errorPacket != null)
return container.errorPacket;
if (container.messagePacket != null)
return container.messagePacket;
if (container.invalidPacket != null)
return container.invalidPacket;
if (container.unifyRequestPacket != null)
return container.unifyRequestPacket;
if (container.unifyResultPacket != null)
return container.unifyResultPacket;
if (container.debugPacket != null)
return container.debugPacket;
if (container.setAutoclosePacket != null)
return container.setAutoclosePacket;
// Add new packets here and in the serialize method
throw new RuntimeException("Cannot map received json to any known packet class");
} catch (Exception e) {
(new Logger()).exception(e);
InvalidPacket packet = new InvalidPacket();
packet.error = e.getMessage();
return packet;
}
}
}
@@ -0,0 +1,32 @@
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();
}
}
@@ -0,0 +1,164 @@
package de.dhbwstuttgart.server.packet;
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.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialValue;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.PlaceholderRegistry;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.util.Logger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import org.java_websocket.WebSocket;
/**
* 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 SerialMap finiteClosure;
public SerialMap constraintSet;
public SerialMap unifyConstraintSet;
public SerialMap serialKeyStorage;
public SerialValue<?> placeholders;
public SerialList<SerialMap> factoryplaceholders;
public String futureId;
public int logLevel;
@JsonIgnore
private KeyStorage keyStorage = new KeyStorage();
@JsonIgnore
private boolean keyStorageLoaded = false;
public static UnifyRequestPacket create(
FiniteClosure finiteClosure,
ConstraintSet<Pair> constraintSet,
ConstraintSet<UnifyPair> unifyConstraintSet,
PlaceholderRegistry placeholderRegistry
) {
UnifyRequestPacket packet = new UnifyRequestPacket();
// store constraint and finite closure
packet.finiteClosure = finiteClosure.toSerial(packet.keyStorage);
packet.constraintSet = constraintSet.toSerial(packet.keyStorage);
packet.unifyConstraintSet = unifyConstraintSet.toSerial(packet.keyStorage);
// store placeholder registry
var serialRegistry = placeholderRegistry.toSerial(packet.keyStorage);
packet.placeholders = serialRegistry.getValue("ph");
packet.factoryplaceholders = serialRegistry.getList("factoryPh").assertListOfMaps();
// store referenced objects separately
packet.serialKeyStorage = packet.keyStorage.toSerial(packet.keyStorage);
packet.logLevel = ConsoleInterface.logLevel.getValue();
return packet;
}
@JsonIgnore
public void loadKeyStorage(UnifyContext context) {
if (!keyStorageLoaded) {
keyStorageLoaded = true;
keyStorage = KeyStorage.fromSerial(this.serialKeyStorage, context);
}
}
@JsonIgnore
private FiniteClosure retrieveFiniteClosure(UnifyContext context) {
this.loadKeyStorage(context);
return FiniteClosure.fromSerial(this.finiteClosure, context, keyStorage);
}
@JsonIgnore
private ConstraintSet<Pair> retrieveConstraintSet(UnifyContext context) {
this.loadKeyStorage(context);
return ConstraintSet.fromSerial(this.constraintSet, context, Pair.class, keyStorage);
}
@JsonIgnore
private ConstraintSet<UnifyPair> retrieveUnifyConstraintSet(UnifyContext context) {
this.loadKeyStorage(context);
return ConstraintSet.fromSerial(this.unifyConstraintSet, context, UnifyPair.class, keyStorage);
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketServer socketServer) {
socketServer.sendMessage(webSocket, "You requested a unify! Please wait until I calculated everything...");
socketServer.log(webSocket, "Client requested a unification. Starting now...");
try {
var placeholderRegistry = new PlaceholderRegistry();
ArrayList<String> existingPlaceholders = (ArrayList) this.placeholders.getOf(ArrayList.class);
existingPlaceholders.forEach(placeholderRegistry::addPlaceholder);
Logger logger = new ServerTaskLogger(
webSocket,
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
);
this.factoryplaceholders.stream()
.map(p -> (PlaceholderType)UnifyType.fromSerial(p, unifyContext))
.forEach(placeholderRegistry.UnifyTypeFactory_PLACEHOLDERS::add);
// start the unification algorithm from the received data
IFiniteClosure finiteClosure = this.retrieveFiniteClosure(unifyContext);
ConstraintSet<Pair> constraintSet = this.retrieveConstraintSet(unifyContext);
ConstraintSet<UnifyPair> unifyConstraintSet = this.retrieveUnifyConstraintSet(unifyContext);
var resultModel = new UnifyResultModel(constraintSet, finiteClosure);
UnifyResultListenerImpl resultListener = new UnifyResultListenerImpl();
resultModel.addUnifyResultListener(resultListener);
TypeUnify.unifyParallel(
unifyConstraintSet.getUndConstraints(),
unifyConstraintSet.getOderConstraints(),
finiteClosure,
unifyContext.newWithResultModel(resultModel)
);
var resultSets = resultListener.getResults();
socketServer.log(webSocket, "Finished unification");
socketServer.sendMessage(webSocket, "Unification finished. Found " + resultSets.size() + " result sets");
if (webSocket.isOpen()) {
UnifyResultPacket resultPacket = UnifyResultPacket.create(resultSets, futureId);
webSocket.send(PacketContainer.serialize(resultPacket));
}
} catch (Exception e) {
SocketServer.logger.exception(e);
socketServer.log(webSocket, e.getMessage());
}
}
@JsonIgnore
public SocketFuture<UnifyResultPacket> getFuture() {
var future = new SocketFuture<>(List.of(UnifyResultPacket.class));
futureId = future.futureId;
return future;
}
}
@@ -0,0 +1,45 @@
package de.dhbwstuttgart.server.packet;
import com.fasterxml.jackson.annotation.JsonIgnore;
import de.dhbwstuttgart.server.SocketClient;
import de.dhbwstuttgart.server.packet.dataContainers.KeyStorage;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialList;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.util.List;
import org.java_websocket.WebSocket;
/**
* A packet to send all calculated data from the unification algorithm back to the client
*/
public class UnifyResultPacket implements IServerToClientPacket {
public SerialList<ISerialNode> results;
public SerialMap keyStorage;
public String futureId;
public static UnifyResultPacket create(List<ResultSet> resultSets, String futureId) {
UnifyResultPacket serialized = new UnifyResultPacket();
KeyStorage keyStorage = new KeyStorage();
serialized.results = SerialList.fromMapped(resultSets, resultSet -> resultSet.toSerial(keyStorage));
serialized.keyStorage = keyStorage.toSerial(keyStorage);
serialized.futureId = futureId;
return serialized;
}
@JsonIgnore
public List<ResultSet> getResultSet(UnifyContext context) {
return this.results.assertListOfMaps().stream()
.map(resultData -> ResultSet.fromSerial(resultData, context)).toList();
}
@JsonIgnore
public void onHandle(WebSocket webSocket, SocketClient socketClient) {
SocketClient.logger.info("Received unify result");
socketClient.completeResponseFuture(futureId, this);
}
}
@@ -0,0 +1,16 @@
package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.ISerialNode;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
public interface ISerializableData {
public abstract ISerialNode toSerial(KeyStorage keyStorage);
public static Object fromSerial(SerialMap data, UnifyContext context) {
throw new NotImplementedException("Missing implementation of \"fromSerial\" for a serializable element");
}
}
@@ -0,0 +1,103 @@
package de.dhbwstuttgart.server.packet.dataContainers;
import de.dhbwstuttgart.server.packet.dataContainers.serialized.SerialMap;
import de.dhbwstuttgart.typeinference.unify.UnifyContext;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public class KeyStorage implements ISerializableData {
/**
* Store a unique identifier for every element, so it can be referenced in the json
*/
protected AtomicInteger identifierCount = new AtomicInteger();
/**
* Store the serialized element per identifier when serializing
*/
protected SerialMap serializedElements = new SerialMap();
/**
* Store the unserialized element per identifier when unserializing
*/
protected Map<String, ISerializableData> unserializedElements = new HashMap<>();
/**
* Retrieve or generate a new identifier for a constraint
*/
public String getIdentifier() {
return this.identifierCount.incrementAndGet() + "_";
}
/**
* Checks if the given element identifier belongs to an element that was already serialized
*/
public boolean isAlreadySerialized(String identifier) {
return this.serializedElements.containsKey(identifier);
}
/**
* Checks if the given element identifier belongs to a element that was already unserialized
*/
public boolean isAlreadyUnserialized(String identifier) {
return this.unserializedElements.containsKey(identifier);
}
/**
* Register a serialized element to prevent it from being serialized again
*/
public void putSerialized(String identifier, SerialMap serializedElement) {
this.serializedElements.put(identifier, serializedElement);
}
/**
* Retrieve a serialized element
*/
public SerialMap getSerialized(String identifier) {
if (!this.serializedElements.containsKey(identifier)) {
throw new RuntimeException("No serialized element of identifier " + identifier + " available to get");
}
return this.serializedElements.getMap(identifier);
}
/**
* Register an unserialized element to prevent it from being unserialized again
*/
public void putUnserialized(String identifier, ISerializableData element) {
this.unserializedElements.put(identifier, element);
}
/**
* Retrieve an unserialized element
*/
public <T extends ISerializableData> T getUnserialized(String identifier, Class<T> target) {
if (!this.unserializedElements.containsKey(identifier)) {
throw new RuntimeException("No unserialized element of identifier " + identifier + " available to get");
}
var element = this.unserializedElements.get(identifier);
if (target.isInstance(element)) {
return (T) element;
}
throw new RuntimeException("Failed to get unserialized element from KeyStorage. Expected instance of " +
target.getName() + " but found " + element.getClass().getName());
}
@Override
public SerialMap toSerial(KeyStorage keyStorage) {
SerialMap serialized = new SerialMap();
serialized.put("serializedElements", this.serializedElements);
return serialized;
}
public static KeyStorage fromSerial(SerialMap data, UnifyContext context) {
var serializedConstraintsData = data.getMap("serializedElements");
var constraintContext = new KeyStorage();
for (var entry : serializedConstraintsData.entrySet()) {
if (entry.getValue() instanceof SerialMap valueMap) {
constraintContext.putSerialized(entry.getKey(), valueMap);
}
}
return constraintContext;
}
}

Some files were not shown because too many files have changed in this diff Show More