2
0

Compare commits

..

250 Commits

Author SHA1 Message Date
6247416e6c newest state 2024-04-27 17:37:15 +02:00
514a504f0f little progress 2024-04-22 22:13:21 +02:00
e9722e595c little progress 2024-04-22 22:12:55 +02:00
cb7c81c41b newest state. something wrong with calling java-tx with multiple files 2024-04-22 01:06:03 +02:00
51b676a98a update compile.sh to use old state, because multiple source files at once very slow/not working 2024-04-10 14:43:09 +02:00
18728712d3 newest compiler versions state 2024-04-10 14:41:05 +02:00
9ec4d59f24 newest state 2024-04-02 23:45:56 +02:00
5d65f007bd add new compiler versions 2024-04-02 23:44:41 +02:00
228b2b1596 update compile.sh to work on macos (hopefully) 2024-03-16 17:27:12 +01:00
5bee05ac43 update files to match newest version 2024-03-16 17:16:23 +01:00
518a09b00f update compile.sh 2024-03-16 17:14:51 +01:00
c8a043219e add most recent jars 2024-03-15 20:22:29 +01:00
24bcdf9dd8 update compile.sh to use relative paths 2024-03-15 20:16:26 +01:00
2b767f1f4f replace makefile (which never worked very well) with custom bash script to generate class files and rollback some migrations to .jav which broke code 2024-03-15 19:59:58 +01:00
427e568ff8 trying to get more jav files working 2024-03-13 19:27:01 +01:00
a6558ae7b5 progress converting some files to jav and newest jtx-compiler jars 2024-03-12 20:05:26 +01:00
2309bf4511 add new version of javatx compiler 2024-02-08 13:04:34 +01:00
abbd9cdcd9 update src files to be up to date 2024-02-06 10:04:32 +01:00
cdd4afb986 let makefile automatically create destination dir if not existent 2024-02-06 09:48:24 +01:00
6897e13c43 changed structure for better debugging 2024-02-02 13:06:37 +01:00
ceae302fa6 add antlr files 2024-01-25 11:16:25 +01:00
175023607e add current compiler versions 2024-01-25 11:15:27 +01:00
1e8444d5ff trying to add more classes, currently failing 2024-01-25 11:05:51 +01:00
e0775b463a added dependencies 2024-01-11 14:23:16 +01:00
c9f125941d makefile is hopefully working now and able to compile projects with .java and .jav files 2023-12-12 17:39:04 +01:00
f093edb74f trying to also compile .jav files, not running yet 2023-11-23 17:08:47 +01:00
8ea459fcd7 added makefile that can compile all .java files and maintain the package structure 2023-11-23 16:20:44 +01:00
a84d1ffdd7 modified: ../src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
Resultmodell aktiviert
	modified:   ../src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
a < void und void < a => a = void.
2023-11-08 18:28:54 +01:00
a3d63a0266 modified: ../src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../src/test/java/TestComplete.java
2023-11-08 18:10:56 +01:00
dcc2da85c5 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-11-07 00:13:53 +01:00
6f193b19ab modified: src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
modified:   src/test/java/TestComplete.java
2023-11-07 00:13:43 +01:00
1c55954e5c Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-11-06 12:31:27 +01:00
ec04f01a10 Allow relative paths by getting the absolute file (seriously Java) 2023-11-06 12:30:42 +01:00
78a2fddc21 modified: ../../../../../resources/bytecode/javFiles/Cycle.class 2023-11-03 20:30:22 +01:00
44f8899157 Merge branch 'targetBytecode' of gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-11-03 20:26:41 +01:00
d1a6dcbbac modified: core/JavaTXCompiler.java
modified:   typeinference/constraints/ConstraintSet.java
	modified:   typeinference/unify/TypeUnifyTask.java
2023-11-03 20:25:17 +01:00
15150fca9e modified: ../../../src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java 2023-11-03 18:56:31 +01:00
fba7f0ee81 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-11-03 18:42:09 +01:00
e0da2a4c46 modified: Cycle.class
modified:   LambdaRunnable.jav
	modified:   ../../../src/test/java/TestComplete.java
2023-11-03 18:41:17 +01:00
f588ece7c3 Fix up runnable 2023-11-03 15:45:14 +01:00
9ad5b76542 Fix up bad error handling 2023-11-03 10:26:43 +01:00
3d2c699964 Fix up functional interface 2023-11-02 15:46:40 +01:00
f95c3c5fcf Fix up method resolution 2023-11-02 15:25:25 +01:00
4654ecacaf Some changes in how overload resolution works 2023-11-02 13:07:42 +01:00
1be27746e3 Allow Void as return type for Lambdas 2023-10-31 14:26:43 +01:00
c51190feef Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-10-27 21:19:30 +02:00
c4ce97f20c Anpassung zur Integration von Functional Interfaces und FunN$$-Typen
modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/Record.java
	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
	modified:   src/test/java/targetast/ASTToTypedTargetAST.java
2023-10-27 21:17:52 +02:00
837317c84c Make System.out.println work 2023-10-27 15:28:46 +02:00
df852ef36e Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-10-27 14:33:21 +02:00
c00722823a Functional Interfaces und Funn&&-Typen integriert.
modified:   resources/bytecode/javFiles/LambdaRunnable.jav
	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IFiniteClosure.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
	modified:   src/test/java/TestComplete.java
2023-10-27 14:29:27 +02:00
e31f1c59e1 Examples 2023-10-27 14:27:47 +02:00
5d0d7a6d94 Translate for loop 2023-10-24 17:34:06 +02:00
b372c6ac1c More work on static, references to other classes 2023-10-24 15:17:13 +02:00
124dea2e58 Static blocks (might be needed for something) 2023-10-24 12:05:19 +02:00
eaef00ff54 Static but no static blocks yet 2023-10-23 16:44:12 +02:00
892ba5fff0 Add interfaces 2023-10-19 17:02:22 +02:00
628f1631e8 Allow packages 2023-10-18 16:54:41 +02:00
0b815950e1 Remove empty files 2023-10-17 12:31:29 +02:00
f10e7e6d72 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-10-17 12:27:52 +02:00
700ecf3e5d Changes from weeks ago, needs review 2023-10-17 12:26:40 +02:00
f7c53fc6c3 modified: src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Kommentar "In commit dfd91b5f8b eingefuegt" eingefuegt
2023-10-07 20:30:37 +02:00
9764ec6db1 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-10-07 07:24:59 +02:00
b21faa30fc new file: S2023_Luca_Trumpfheller.pdf 2023-10-05 15:52:48 +02:00
87f8b8799e modified: src/test/java/AllgemeinTest.java 2023-10-05 15:49:09 +02:00
769f1bb677 Progress on implementing the basic case 2023-09-01 18:26:01 +02:00
5623fdc020 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-09-01 17:20:34 +02:00
dfd91b5f8b TESTEN OB DAS SINN MACHT
modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   src/test/java/AllgemeinTest.java
2023-09-01 17:18:51 +02:00
3c43978c55 Less general type 2023-09-01 12:51:06 +02:00
fb7b51a971 Point out what the goal translation is 2023-09-01 12:34:43 +02:00
56c360104b TripleTest 2023-08-30 11:28:17 +02:00
e414da3369 Simple record patterns in method headers 2023-08-18 17:15:15 +02:00
5f1f698530 Refactor 2023-08-18 15:15:40 +02:00
729e88bc6d Add test for instanceof 2023-08-18 11:35:01 +02:00
bffc7f9f1c Remove TypePattern and replace it with FormalParameter 2023-08-17 16:25:19 +02:00
011b272af6 Fix missing constraints 2023-08-17 16:15:38 +02:00
ee359da751 Refactor Patterns 2023-08-17 15:56:16 +02:00
6025e17186 Infer String/Integer for patterns 2023-08-17 15:22:53 +02:00
93d7aca9e6 Switch on Strings 2023-08-17 14:23:19 +02:00
677c784b6d Allow single expressions in switch expression 2023-08-17 13:26:30 +02:00
e69a367c33 Add printout 2023-08-17 10:17:09 +02:00
14d0475d59 Type inference for switch 2023-08-17 09:27:24 +02:00
762d344e42 Make switches work with set types 2023-08-16 17:13:28 +02:00
be5591f7dc Rename files for macos and windows 2023-08-15 17:17:17 +02:00
7193f5a646 Workaround for eclipse 2023-08-15 16:52:54 +02:00
f46c2ad0f7 New test case 2023-08-01 14:02:19 +02:00
b0f7a264c2 Implement records 2023-07-31 15:11:35 +02:00
4f3164a48a Allow the first patterns 2023-07-28 12:05:30 +02:00
be55d661cb Add classic switch 2023-07-27 10:02:28 +02:00
3de9fde672 Add new target ast nodes and test cases for switch 2023-07-26 15:47:30 +02:00
a0582e918b Merge 2023-07-25 15:06:15 +02:00
18429d9cf9 Iteration.jav Pair ausgeklammert 2023-07-18 11:45:17 +02:00
b65df7c390 Merge branch 'targetBytecode' of gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-07-18 11:44:43 +02:00
22d1be5ea4 Fixed expected AST for Instanceof.jav 2023-07-17 19:55:16 +02:00
18fc82f036 Merge branch 'patternMatching' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into patternMatching 2023-07-17 19:53:16 +02:00
f5b843ec11 Extended instanceOfTest 2023-07-17 19:52:30 +02:00
bad5d26969 Extended instanceOfTest 2023-07-17 19:50:58 +02:00
951d741d90 Added test for Sealed classe and interface ASTs 2023-07-17 19:38:01 +02:00
fe6c9858a2 Finalized test cases for new jav-files 2023-07-17 17:58:39 +02:00
1df354d5f1 Modified InstanceOf to use Pattern 2023-07-17 17:49:28 +02:00
6119bc92ed Corrected ASTPrinter for RecordPattern 2023-07-15 22:05:34 +02:00
e8140b3160 Added method stubs in visitors for new AST nodes 2023-07-15 21:41:50 +02:00
75789e574e Modified ASTPrinter to support new AST nodes for tests 2023-07-15 21:41:27 +02:00
c0c46e197f Added sealed classes to AST 2023-07-14 08:52:51 +02:00
a0e6df7cfd new file: resources/AllgemeinTest/Twice2.jav
modified:   src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   src/test/java/AllgemeinTest.java
2023-07-13 15:25:34 +02:00
1643412f1b Added nestedPatterns 2023-07-12 21:54:17 +02:00
3ed6edc323 Added SwitchExpression to AST 2023-07-12 21:43:50 +02:00
fa7a331a66 Beginning of switchExpression for AST 2023-07-11 22:15:35 +02:00
939d402b1e Changed GatherNames to add types declared inside of other types to the JavaClassRegistry 2023-07-07 09:24:45 +02:00
492cbe48e9 Created RecordPattern & started development with test cases 2023-07-06 22:15:40 +02:00
a17e1f473a Catch linkage error 2023-07-05 15:48:27 +02:00
359f3e68ab Added SwitchStmt including Type & GuardedPattern to AST 2023-07-04 15:27:29 +02:00
5c62191f3b Consider constructors when creating class generics 2023-07-04 12:17:14 +02:00
b04201de42 Don't load classes that get compiled by a source file 2023-07-04 11:40:23 +02:00
a15cbcba7b Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-07-03 11:54:30 +02:00
9019d90b1e Please enter the commit message for your changes. Lines starting
with '#' will be ignored, and an empty message aborts the commit.
2023-07-03 11:53:15 +02:00
d07b2bdf0a Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-07-03 10:13:59 +02:00
d05054755c Fix bug 2023-07-03 10:13:01 +02:00
1a89920430 Created AST node TypePattern and adapted test cases in TestNewFeatures 2023-06-28 22:52:18 +02:00
54a836b734 Added missing version to pom.xml 2023-06-28 22:12:28 +02:00
8b3b07e32c Added test case Record(.jav) in TestNewFeatures 2023-06-28 22:10:08 +02:00
d55b402269 Some fixes 2023-06-28 14:09:24 +02:00
24900b8fcc Added test case for instanceof in syntaxtreegenerator 2023-06-27 20:25:31 +02:00
2368a087c0 Added BoolExpression and instanceof to AST 2023-06-27 20:25:05 +02:00
994a1571b7 Changed resources path in TestCodegen after merge 2023-06-27 19:14:28 +02:00
aed1d3848b Resolved last merge conflict 2023-06-27 18:48:18 +02:00
93cf39cfe9 Merge branch 'bigRefactoring' into patternMatching 2023-06-27 18:46:57 +02:00
bdaf578f86 Fix equality 2023-06-27 15:48:15 +02:00
6079e96efa Test more thoroughly and add a new infimum deletion strategy 2023-06-27 15:01:28 +02:00
bb01e78123 Undo that change 2023-06-27 09:51:07 +02:00
41d8e223ce Fixed wrong resources path in TestCodegen 2023-06-26 20:24:59 +02:00
e1e1f3eafc Insert missing case 2023-06-26 13:14:53 +02:00
9c1e016bb1 Merge and fix folder structure 2023-06-26 12:31:00 +02:00
eaeb3c4106 Modified expected AST for Faculty according to Faculty.jav 2023-06-24 19:48:36 +02:00
1fb431ab36 After merge fixes Codegen.java 2023-06-24 19:45:08 +02:00
124313cb16 Merge remote-tracking branch 'origin/bigRefactoring' into patternMatching 2023-06-24 19:09:39 +02:00
d48b888075 Bug fixes, TestComplete in 'syntaxtreegenerator' runs without error 2023-06-24 18:54:31 +02:00
f5aa90bdbd Add Cycle class (again) 2023-06-23 09:40:23 +02:00
4bcb91ce2d Refactor bounds to make the invocation smaller 2023-06-22 17:13:15 +02:00
97a1bcbbe1 Fix T1 & T2 refering to method signature instead of actual types 2023-06-22 17:13:01 +02:00
f32b1ee5b2 Fix auxiliary files not containing parent interface 2023-06-22 14:32:41 +02:00
711aa70d48 Update to java 20 and some refactoring 2023-06-22 09:34:15 +02:00
168a499811 Set typeinfernce tests to be ignored 2023-06-21 21:38:58 +02:00
d52fbeb1ae Moved all javFiles to test/resources/javFiles and removed unused resources 2023-06-21 21:06:14 +02:00
ce0ef10c8d Added missing AST blueprint for 'syntaxtreegenerator' tests 2023-06-21 21:02:53 +02:00
81e19f5315 Fixed syntaxtreegenerator to determine correct receiver of methodcall 2023-06-21 20:46:23 +02:00
89a791b81e Fixed NotImplemented for field accesses in "dottexression" 2023-06-21 19:56:16 +02:00
2d1caf9ded fix stash 2023-06-21 18:24:09 +02:00
49b0494f36 Removed file to fix stashes 2023-06-21 18:21:59 +02:00
60e2d8177b fix idTest() in syntaxtreegenerator 2023-06-21 18:18:38 +02:00
62e7a1c871 Bug fix and test exclusion 2023-06-21 10:10:32 +02:00
761dd48fa1 Test directory cleanup 2023-06-21 09:37:58 +02:00
4a18a81b33 Alter tests a bit 2023-06-15 16:31:50 +02:00
9eb0dd1cf5 Iteration 2023-06-15 14:13:15 +02:00
bb0ee7d517 Refactoring 2023-06-13 16:33:54 +02:00
fe2b3accb3 Fix not looking up the tph in equality 2023-06-13 10:28:20 +02:00
78ad7bc003 Fixed bugs in StatementGenerator regarding constructor generation and field accesses 2023-06-09 17:26:55 +02:00
f08744479a Started test driven bug fixing for SyntaxTreeGenerator 2023-06-07 22:24:16 +02:00
bf15ff693e Created TestComplete for unit SyntaxTreeGenerator 2023-06-07 21:08:46 +02:00
48199b5d2e Created test suite for syntaxtreegenerator including resources 2023-06-06 21:21:26 +02:00
7556b9f590 Fixed parser bug that caused TestComplete to fail 2023-06-06 19:43:56 +02:00
03b7f12541 Merge 2023-06-06 16:36:12 +02:00
ecc5dfcef6 Add class file 2023-06-06 16:35:42 +02:00
f33aab9cfb Merge 2023-06-06 16:16:41 +02:00
3875de7f80 Fix local variable conversion and not loading interfaces 2023-06-06 13:46:53 +02:00
69f44c2927 Merge branch 'targetBytecode' of gohorb.ba-horb.de:/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-06-06 10:17:01 +02:00
26398a692f modified: resources/AllgemeinTest/Iteration.jav 2023-06-06 10:16:54 +02:00
e13baa8acb modified: resources/AllgemeinTest/Iteration.jav 2023-06-05 15:25:55 +02:00
3c86eecf8b modified: ../../pom.xml
new file:   Iteration.jav
	modified:   Pair.jav
	modified:   ../../src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   ../../src/test/java/AllgemeinTest.java
2023-06-05 13:14:00 +02:00
63c5cb8390 Moved test resources to src/test and refactored tests 2023-06-05 09:28:55 +02:00
e3edd0410a added astprinter to parsertest 2023-06-03 18:59:11 +02:00
eb5cf1ab33 StackOverflow fix switchexpression 2023-06-03 17:54:37 +02:00
b409175a25 Add --enable-preview to surefire test plugin 2023-06-03 17:33:08 +02:00
a54938cb65 bug fix empty param list 2023-06-01 21:18:08 +02:00
30a62a6621 bug fix VectorNotObject test 2023-06-01 20:59:16 +02:00
dce3ed8051 Some fixes for the plugin 2023-06-01 16:13:03 +02:00
8e5a20e59e Fix incorrect signature 2023-05-31 11:38:47 +02:00
337ff8b865 Fix incorrect signatures 2023-05-24 16:51:53 +02:00
1d7e755a98 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-05-24 13:53:36 +02:00
67a582b4a2 Flatten generic function types 2023-05-24 13:53:23 +02:00
034a398515 Merge branch 'targetBytecode' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into targetBytecode 2023-05-22 14:40:50 +02:00
58a72b0286 new file: resources/AllgemeinTest/StreamTest.jav
modified:   src/test/java/AllgemeinTest.java
2023-05-22 14:40:35 +02:00
677d68428d Merge branch 'fixPlugin' into targetBytecode 2023-05-16 14:52:45 +02:00
d2ef5ccb24 Update plugin installation 2023-05-16 14:52:31 +02:00
66944cf3c1 Recursively collect generics for FunN 2023-05-15 16:52:20 +02:00
9d9a1f6614 modified: src/test/java/AllgemeinTest.java
Twice in Allgemeintest reingenommen
2023-05-10 13:27:13 +02:00
0b33948945 modified: resources/insertGenericsJav/TestContraVariant.jav 2023-05-09 14:36:07 +02:00
5e1631439a modified: resources/insertGenericsJav/TestContraVariant.jav 2023-05-09 14:28:32 +02:00
8992260264 TestContraVariant 2023-05-09 12:18:12 +02:00
f8f76e9f7d WIP 2023-05-08 13:32:39 +02:00
52b7040337 Break statement in AST eingefügt 2023-04-01 16:27:55 +02:00
4986fd0f31 Merge branch 'bigRefactoring' into patternMatching 2023-04-01 15:41:36 +02:00
dc8578632c Records in AST aufgenommen 2023-04-01 15:40:12 +02:00
9a780127c0 Grammatik um recordPattern erweitert 2023-03-24 04:44:52 +01:00
0311f5ed77 Test Case für geschachtelte Pattern erstellt 2023-03-22 18:42:13 +01:00
b1b7c23166 Switch statement in GatherNames für verschieden Deklarations-Typen 2023-03-22 18:41:59 +01:00
0ca32ca6a7 modified: README_aktuelle_Branches 2023-03-21 10:35:23 +01:00
1ab0f42fd1 Bug fixes für GeneralParserTest und Mehrfachaufrufe des Parsers entfernt 2023-03-20 22:07:47 +01:00
856d343ed3 Consider public and standard constructors ones 2023-03-20 19:09:47 +01:00
2c7037708b Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2023-03-20 18:26:47 +01:00
78a898db37 Bug fixes für Tests in 'parser' 2023-03-20 03:03:37 +01:00
aeb4b18069 delete old parser files 2023-03-15 19:26:23 +01:00
79c82c122a fix for new-Statement generation. Change FieldInitialization Test 2023-03-15 19:25:35 +01:00
27ee00b069 Changed Parser Test 2023-03-15 19:07:41 +01:00
af28e033a2 Merge branch 'patternMatching' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into patternMatching 2023-03-15 18:49:34 +01:00
761e693984 Set --enable-preview for maven compile and test 2023-03-15 18:49:29 +01:00
d6c22a60bc 'Illegal fallthrough' entfernt 2023-03-15 18:44:00 +01:00
a8012a3ea6 'Illegal fallthrough' entfernt 2023-03-15 18:41:04 +01:00
31ee90b3ff Umwandlung von Interfaces implementiert 2023-03-15 05:14:43 +01:00
96d19efa5d Umwandlung von Konstruktoren in eigener Methode 2023-03-12 21:50:53 +01:00
1919e34eed Debugging komplett für test parser/AntlrTest.jav 2023-03-10 20:30:15 +01:00
043dda660b Fehler im neuen SyntaxTreeGenerator beseitigt und TODOs eingefügt 2023-03-10 07:48:38 +01:00
8c6a614157 Merge remote-tracking branch 'origin/bigRefactoring' into patternMatching 2023-03-08 06:42:08 +01:00
09cc88062e StatementGenerator fertiggestellt 2023-03-08 06:35:55 +01:00
2197e09307 Merge branch 'targetBytecode' into bigRefactoring 2023-03-01 16:34:14 +01:00
d362858184 Umbau des StatementGenerators fortgeführt 2023-03-01 06:49:59 +01:00
c118c05bb2 Umwandlung von Methodenaufrufen implementiert 2023-02-26 21:04:51 +01:00
aa5f79257e Antlr labels für ExpressionContext eingeführt, um StatementGenerator weiterzuentwickeln 2023-02-22 22:43:25 +01:00
f282d7a212 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2023-02-21 14:51:08 +01:00
4c685a9ed9 Merge branch 'targetBytecode' into bigRefactoring 2023-02-21 14:48:28 +01:00
55636436d2 Fix Antlr Version 2023-02-14 18:03:12 +01:00
5981a9362c Fix console interface 2023-02-14 13:42:56 +01:00
c38bf658fc Anpassung Statementexpression an Java17-Grammatik begonnen 2023-02-13 08:16:16 +01:00
0e981ce95c convert(StatementContext) Implementierung fortgesetzt 2023-02-12 07:51:31 +01:00
40d0d6b63e TypeGenerator für Java17 Grammatik angepasst 2023-02-05 09:16:59 +01:00
a77970b5e7 TypeGenerator für Rework vorbereitet 2023-02-03 07:58:06 +01:00
ca327375c8 Konvertierung von Methoden begonnen 2023-02-02 06:38:30 +01:00
4f4ca50c75 Implementierung ConvertClass-Methode in ASTGen fortgesetzt 2023-01-24 08:14:14 +01:00
1cf23bec90 Implementierung neuer ASTGen fortgesetzt 2023-01-21 05:35:15 +01:00
3bdc3b764d Merge remote-tracking branch 'origin/bigRefactoring' into patternMatching 2023-01-20 06:16:25 +01:00
a13294edf4 Visitor Ansatz verworfen, STG in ASTGen neu aufsetzen 2023-01-20 06:13:38 +01:00
a85b60b95f ASTGen auf basis von antlr visitor 2023-01-20 02:54:59 +01:00
def76724b5 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2023-01-17 19:30:47 +01:00
eb5a339f56 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2023-01-17 17:42:58 +01:00
d6b25bc76e Add jar-building to pom-file. Fix ConsoleInterface 2023-01-17 17:42:32 +01:00
c78a148766 Alternativ-labels in grammatik & neuen ast-generator auf basis von antlr visitor 2023-01-17 06:38:00 +01:00
cb564dc436 Beginn anpassung SyntaxTreeGenerator an neue Grammatik 2023-01-17 06:37:07 +01:00
6d52949215 Anpassungen der Grammatikregeln übernommen 2023-01-17 06:34:39 +01:00
b0bec83900 workaround für java 17/19 probleme & paket ergänzt 2023-01-17 06:28:19 +01:00
0ee3117d6e Test für Java17 Grammatik-Konstrukte hinzugefügt 2023-01-11 17:43:08 +01:00
96142339e0 deleted: src/test/java/targetast/Fun1$$.java 2023-01-10 16:41:44 +01:00
3cf076fd82 deleted: Studienarbeiten/.new.Studienar
renamed:    Studienarbeiten/S2003_Felix_Reichenbach.pdf -> Studienarbeiten_Bachelorarbeiten/S2003_Felix_Reichenbach.pdf
	renamed:    Studienarbeiten/S2004_Markus_Haas.pdf -> Studienarbeiten_Bachelorarbeiten/S2004_Markus_Haas.pdf
	renamed:    Studienarbeiten/S2004_Thomas_Ott.pdf -> Studienarbeiten_Bachelorarbeiten/S2004_Thomas_Ott.pdf
	renamed:    Studienarbeiten/S2005_Joerg_Baeuerle.pdf -> Studienarbeiten_Bachelorarbeiten/S2005_Joerg_Baeuerle.pdf
	renamed:    Studienarbeiten/S2005_Markus_Melzer.pdf -> Studienarbeiten_Bachelorarbeiten/S2005_Markus_Melzer.pdf
	renamed:    Studienarbeiten/S2006_Juergen_Schmiing.pdf -> Studienarbeiten_Bachelorarbeiten/S2006_Juergen_Schmiing.pdf
	renamed:    Studienarbeiten/S2006_Thomas_Hornberger.pdf -> Studienarbeiten_Bachelorarbeiten/S2006_Thomas_Hornberger.pdf
	renamed:    Studienarbeiten/S2006_Timo_Holzherr.pdf -> Studienarbeiten_Bachelorarbeiten/S2006_Timo_Holzherr.pdf
	renamed:    Studienarbeiten/S2007_Achim_Burger.pdf -> Studienarbeiten_Bachelorarbeiten/S2007_Achim_Burger.pdf
	renamed:    Studienarbeiten/S2007_Arne_Luedtke.pdf -> Studienarbeiten_Bachelorarbeiten/S2007_Arne_Luedtke.pdf
	renamed:    Studienarbeiten/S2008_Christian_Stresing.pdf -> Studienarbeiten_Bachelorarbeiten/S2008_Christian_Stresing.pdf
	renamed:    Studienarbeiten/S2008_Thorsten_Hake.pdf -> Studienarbeiten_Bachelorarbeiten/S2008_Thorsten_Hake.pdf
	renamed:    Studienarbeiten/S2008_Thorsten_Hake_Christian_Stresing_Eclipse_Plugin.pdf -> Studienarbeiten_Bachelorarbeiten/S2008_Thorsten_Hake_Christian_Stresing_Eclipse_Plugin.pdf
	renamed:    Studienarbeiten/S2008_Thorsten_Hake_Christian_Stresing_Testing.pdf -> Studienarbeiten_Bachelorarbeiten/S2008_Thorsten_Hake_Christian_Stresing_Testing.pdf
	renamed:    Studienarbeiten/S2016_Enrico_Schroedter.pdf -> Studienarbeiten_Bachelorarbeiten/S2016_Enrico_Schroedter.pdf
	renamed:    Studienarbeiten/S2016_Florian_Steurer.pdf -> Studienarbeiten_Bachelorarbeiten/S2016_Florian_Steurer.pdf
	renamed:    Studienarbeiten/S2017_Jan-Elric_Neumann.pdf -> Studienarbeiten_Bachelorarbeiten/S2017_Jan-Elric_Neumann.pdf
	renamed:    Studienarbeiten/S2021_Etienne_Zink.pdf -> Studienarbeiten_Bachelorarbeiten/S2021_Etienne_Zink.pdf
	new file:   Studienarbeiten_Bachelorarbeiten/S2022_Daniel_Holle.pdf
2023-01-10 14:29:59 +01:00
2e4cd0384f Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2022-12-12 14:10:31 +01:00
a7dc943692 Merge remote-tracking branch 'origin/bigRefactoring' into patternMatching 2022-12-04 21:20:09 +01:00
4b6d69d748 Antlr-Grammatik angepasst, um syntaxtree-Klassen zu matchen 2022-12-04 21:17:39 +01:00
1145f010c6 Referenzen auf Parser-Klassen von Java8 zu Java17 umbenannt 2022-12-04 21:15:36 +01:00
d89e414ca7 Alte Java8- durch neue Java17-Grammatik ersetzt 2022-12-03 22:54:22 +01:00
58cd490639 rootDirectory GeneralParserTest, dep. Klasse JavaTXParser 2022-12-01 22:20:39 +01:00
f444003aee Merge branch 'patternMatching' into bigRefactoring 2022-11-28 13:53:39 +01:00
df3e2b55f9 Grammatik-Regeln für "instanceof-PatternMatching" eingefügt 2022-11-24 22:33:23 +01:00
09ac2fc5cf Neue Grammatik-Regeln und daraus resultierende bugfixes 2022-11-22 21:44:13 +01:00
725 changed files with 78695 additions and 9443 deletions
.gitignoreJavaTXcompiler-0.1-jar-with-dependencies.jarJavaTXcompiler-0.2-jar-with-dependencies.jarJavaTXcompiler-0.3-jar-with-dependencies.jarJavaTXcompiler-0.4-jar-with-dependencies.jarJavaTXcompiler-0.5-jar-with-dependencies.jarJavaTXcompiler-0.6-jar-with-dependencies.jarJavaTXcompiler-0.7-jar-with-dependencies.jarJavaTXcompiler-0.8-jar-with-dependencies.jarJavaTXcompiler-0.9-jar-with-dependencies.jarJavaTXcompiler-1.0-jar-with-dependencies.jarJavaTXcompiler-1.1-jar-with-dependencies.jarJavaTXcompiler-1.2-jar-with-dependencies.jarJavaTXcompiler-1.3-jar-with-dependencies.jarJavaTXcompiler-1.4-jar-with-dependencies.jarJavaTXcompiler-1.5-jar-with-dependencies.jarJavaTXcompiler-1.6-jar-with-dependencies.jarJavaTXcompiler-1.7-jar-with-dependencies.jarJavaTXcompiler-1.8-jar-with-dependencies.jarJavaTXcompiler-1.9-jar-with-dependencies.jarJavaTXcompiler-2.0-jar-with-dependencies.jarJavaTXcompiler-2.1-jar-with-dependencies.jarJavaTXcompiler-2.2-jar-with-dependencies.jarJavaTXcompiler-2.3-jar-with-dependencies.jarJavaTXcompiler-2.4-jar-with-dependencies.jarJavaTXcompiler-2.5-jar-with-dependencies.jarREADME_aktuelle_Branchescompile.sh
doc
javatx-src
main
antlr4
de
dhbwstuttgart
java
Main.java
de
dhbwstuttgart
bytecode
core
environment
exceptions
parser
syntaxtree
target
typedeployment
typeinference
util
test
makefilepom.xml
resources
AllgemeinTest
bytecode
insertGenerics
insertGenericsJav
javFiles
packageTest
syntaxtreegenerator
testBytecode
generatedBC
public
src
main
antlr4
de
java
de
dhbwstuttgart
bytecode
core
environment
parser
syntaxtree
target
typedeployment
typeinference
test
target/dependencies

2
.gitignore vendored

@ -19,7 +19,9 @@ bin
.DS_Store
.project
.settings/
.vscode/
/target/
settings.json
#
manually/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -9,3 +9,6 @@ Stand: 24.5.21
simplifyRes, Basis fuer Plugin, sollte auf Plugin gemerged werden, noch keine Packages, Michael
strucTypesNew, Struturelle Typen, alte Basis, arbeite derzeit niemand
Stand 21.2.23
unif23: Testbranch fuer Tagungseinrecihung Unif23

81
compile.sh Executable file

@ -0,0 +1,81 @@
#!/bin/bash
SRCDIR="javatx-src/main/java"
DESTDIR="out"
JAVAC_FLAGS="-g:none -nowarn"
JAVATX_COMPILER_PATH="JavaTXcompiler-2.5-jar-with-dependencies.jar"
#remove all files, if the script is called with parameter "clear"
if [ "$1" = "clean" ]; then
rm -r "$DESTDIR"
exit 0
fi
if [ "$1" != "" ]; then
echo "invalid argument: $1"
exit 1
fi
#find all .java/.jav files and store paths in an array
#note: somehow absolute paths don't work correctly with find -newer
#JAVA_FILES=($(find "$SRCDIR" -name "*.java" -exec realpath {} \;))
#JAV_FILES=($(find "$SRCDIR" -name "*.jav" -exec realpath {} \;))
JAVA_FILES=($(find "$SRCDIR" -name "*.java"))
JAV_FILES=($(find "$SRCDIR" -name "*.jav"))
#create empty arrays for .class file paths
JAVA_CLASSES=()
JAV_CLASSES=()
JAVA_CHANGED=()
JAV_CHANGED=()
mkdir -p $DESTDIR
#fill class files arrays by subsituting .java/.jav -> .class for each file
for file in "${JAVA_FILES[@]}"; do
#substitute destination dir with source dir
class_name="$DESTDIR${file#$SRCDIR}"
#substitute *.java -> *.class
class_name="${class_name%.java}.class"
#if .class file does not exists or .class file older than .java file
if [ ! -f "$class_name" ] || [ "$(find "$file" -prune -newer "$class_name")" ]; then
JAVA_CHANGED+=("$file")
JAVA_CLASSES+=("$class_name")
fi
done
for file in "${JAV_FILES[@]}"; do
#substitute destination dir with source dir
class_name="$DESTDIR${file#$SRCDIR}"
#substitute *.jav -> *.class
class_name="${class_name%.jav}.class"
#if .class file does not exists or .class file older than .jav file
if [ ! -f "$class_name" ] || [ "$(find "$file" -prune -newer "$class_name")" ]; then
JAV_CHANGED+=("$file")
JAV_CLASSES+=("$class_name")
fi
done
#if [ "${#JAV_CHANGED[@]}" -ne 0 ]; then
# echo "java -jar $JAVATX_COMPILER_PATH -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/" ${JAV_CHANGED[@]}"
# java -jar $JAVATX_COMPILER_PATH -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/" "${JAV_CHANGED[@]}"
#fi
if [ "${#JAV_CHANGED[@]}" -ne 0 ]; then
for ((i = 0; i < "${#JAV_CHANGED[@]}"; i++)); do
echo "java -jar $(realpath $JAVATX_COMPILER_PATH) -d $(realpath "$DESTDIR") -cp "$(realpath $SRCDIR):$(realpath $DESTDIR):$(realpath "target/dependencies/")" ${JAV_CHANGED[i]}"
java -jar $JAVATX_COMPILER_PATH -d "$DESTDIR" -cp "$SRCDIR:$DESTDIR:target/dependencies/" "${JAV_CHANGED[i]}"
if [ $? -eq 1 ]; then
exit 1;
fi
done
fi
if [ "${#JAVA_CHANGED[@]}" -ne 0 ]; then
echo "javac -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/*" $JAVAC_FLAGS ${JAVA_CHANGED[@]}"
javac -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/*" $JAVAC_FLAGS "${JAVA_CHANGED[@]}"
fi

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

24
doc/pluginBau.md Normal file

@ -0,0 +1,24 @@
## Bau und installation des Eclipse plugins
1. Zunächst muss der JavaTX Compiler gebaut werden. Dafür wird im Rootverzeichnis des JavaTX Compilers
`mvn install` ausgeführt. Falls die Tests nicht laufen kann das mit `-DskipTests` beseitigt werden.
2. Dann muss das Plugin gebaut werden. Dafür muss ebenfalls `mvn install` ausgeführt werden, im Rootverzeichnis des Plugins.
Falls es dabei zu Fehlern mit der Java-Version kommen sollte muss man in ~\.mavenrc oder \~.mavenrc_pre.bat die Zeile
`set JAVA_HOME=<JDK-19-Pfad>` (Windows) oder `JAVA_HOME="<JDK-19-Pfad>"` (Linux) einfügen. Damit sollte maven korrekt konfiguriert sein.
3. Als letzter Schritt muss nun das Plugin in Eclipse geladen werden. Wichtig dabei ist, dass Eclipse selber mit Java 19 startet.
Dafür kann die Datei `eclipse.ini` angepasst werden die im Installationsverzeichnis von Eclipse vorhanden ist. Hier müssen zwei Zeilen
eingetragen werden:
```
-vm
<JDK-19-Pfad>/javaw.exe
```
Ganz am Anfang der Datei
und unter -vmargs die Option `--enable-preview`
4. Das gebaute Plugin befindet sich unter `JavaCompilerPlugin\releng\JavaCompilerPlugin.Update\target`
Um dieses Plugin in Eclipse laden zu können muss den Dialog `Help > Install new Software` öffnen. Oben rechts steht die Option `Add...`
Im sich öffnenden Dialog muss man `Archive` anklicken und dort das Zip Archiv aus dem Oben genannten Pfad einfügen. Nun mit Add den Dialog schließen.
Als letztes muss in der Liste oben der Eintrag `JavaCompilerPlugin.Update` ausgewählt werden. Hier sollte nun unten das Plugin angezeigt werden.
Einfach auswählen und unten Next drücken. Damit sollte der Vorgang abgeschlossen sein.

@ -0,0 +1,241 @@
/*
[The "BSD licence"]
Copyright (c) 2013 Terence Parr, Sam Harwell
Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8)
Copyright (c) 2021 Michał Lorek (upgrade to Java 11)
Copyright (c) 2022 Michał Lorek (upgrade to Java 17)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
lexer grammar Java17Lexer;
// Keywords
ABSTRACT: 'abstract';
ASSERT: 'assert';
BOOLEAN: 'boolean';
BREAK: 'break';
BYTE: 'byte';
CASE: 'case';
CATCH: 'catch';
CHAR: 'char';
CLASS: 'class';
CONST: 'const';
CONTINUE: 'continue';
DEFAULT: 'default';
DO: 'do';
DOUBLE: 'double';
ELSE: 'else';
ENUM: 'enum';
EXTENDS: 'extends';
FINAL: 'final';
FINALLY: 'finally';
FLOAT: 'float';
FOR: 'for';
IF: 'if';
GOTO: 'goto';
IMPLEMENTS: 'implements';
IMPORT: 'import';
INSTANCEOF: 'instanceof';
INT: 'int';
INTERFACE: 'interface';
LONG: 'long';
NATIVE: 'native';
NEW: 'new';
PACKAGE: 'package';
PRIVATE: 'private';
PROTECTED: 'protected';
PUBLIC: 'public';
RETURN: 'return';
SHORT: 'short';
STATIC: 'static';
STRICTFP: 'strictfp';
SUPER: 'super';
SWITCH: 'switch';
SYNCHRONIZED: 'synchronized';
THIS: 'this';
THROW: 'throw';
THROWS: 'throws';
TRANSIENT: 'transient';
TRY: 'try';
VOID: 'void';
VOLATILE: 'volatile';
WHILE: 'while';
// Module related keywords
MODULE: 'module';
OPEN: 'open';
REQUIRES: 'requires';
EXPORTS: 'exports';
OPENS: 'opens';
TO: 'to';
USES: 'uses';
PROVIDES: 'provides';
WITH: 'with';
TRANSITIVE: 'transitive';
// Local Variable Type Inference
VAR: 'var'; // reserved type name
// Switch Expressions
YIELD: 'yield'; // reserved type name from Java 14
// Records
RECORD: 'record';
// Sealed Classes
SEALED: 'sealed';
PERMITS: 'permits';
NON_SEALED: 'non-sealed';
// Literals
DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?;
HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?;
OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?;
BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?;
FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart? [fFdD]?
| Digits (ExponentPart [fFdD]? | [fFdD])
;
HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?;
BOOL_LITERAL: 'true'
| 'false'
;
CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\'';
STRING_LITERAL: '"' (~["\\\r\n] | EscapeSequence)* '"';
TEXT_BLOCK: '"""' [ \t]* [\r\n] (. | EscapeSequence)*? '"""';
NULL_LITERAL: 'null';
// Separators
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
LBRACK: '[';
RBRACK: ']';
SEMI: ';';
COMMA: ',';
DOT: '.';
// Operators
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: '>>>=';
// Java 8 tokens
ARROW: '->';
COLONCOLON: '::';
// Additional symbols not defined in the lexical specification
AT: '@';
ELLIPSIS: '...';
// Whitespace and comments
WS: [ \t\r\n\u000C]+ -> channel(HIDDEN);
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
// Identifiers
IDENTIFIER: Letter LetterOrDigit*;
// Fragment rules
fragment ExponentPart
: [eE] [+-]? Digits
;
fragment EscapeSequence
: '\\' [btnfr"'\\]
| '\\' ([0-3]? [0-7])? [0-7]
| '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
;
fragment HexDigits
: HexDigit ((HexDigit | '_')* HexDigit)?
;
fragment HexDigit
: [0-9a-fA-F]
;
fragment Digits
: [0-9] ([0-9_]* [0-9])?
;
fragment LetterOrDigit
: Letter
| [0-9]
;
fragment Letter
: [a-zA-Z$_] // these are the "java letters" below 0x7F
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;

@ -0,0 +1,816 @@
/*
[The "BSD licence"]
Copyright (c) 2013 Terence Parr, Sam Harwell
Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8)
Copyright (c) 2021 Michał Lorek (upgrade to Java 11)
Copyright (c) 2022 Michał Lorek (upgrade to Java 17)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
parser grammar Java17Parser;
options { tokenVocab=Java17Lexer; }
sourceFile
: packageDeclaration? importDeclaration* classOrInterface* # srcfile
| moduleDeclaration EOF # moduledecl
;
packageDeclaration
: annotation* PACKAGE qualifiedName ';'
;
importDeclaration
: IMPORT STATIC? qualifiedName ('.' '*')? ';'
;
classOrInterface
: classOrInterfaceModifier*
(classDeclaration | enumDeclaration | interfaceDeclaration | annotationTypeDeclaration | recordDeclaration) # classorinterfacedecl
| ';' # noclassorinterface
;
modifier
: classOrInterfaceModifier
| NATIVE
| SYNCHRONIZED
| TRANSIENT
| VOLATILE
;
classOrInterfaceModifier
: annotation
| PUBLIC
| PROTECTED
| PRIVATE
| STATIC
| ABSTRACT
| FINAL // FINAL for class only -- does not apply to interfaces
| STRICTFP
| SEALED // Java17
| NON_SEALED // Java17
;
variableModifier
: FINAL # finalvarmod
| annotation # annotationvarmod
;
classDeclaration
: CLASS identifier genericDeclarationList?
(EXTENDS typeType)?
(IMPLEMENTS typeList)?
(PERMITS typeList)? // Java17
classBody
;
genericDeclarationList
: '<' genericTypeVar (',' genericTypeVar)* '>'
;
genericTypeVar
: annotation* identifier ((EXTENDS | IMPLEMENTS) annotation* typeBound)?
;
typeBound
: typeType ('&' typeType)*
;
enumDeclaration
: ENUM identifier (IMPLEMENTS typeList)? '{' enumConstants? ','? enumBodyDeclarations? '}'
;
enumConstants
: enumConstant (',' enumConstant)*
;
enumConstant
: annotation* identifier arguments? classBody?
;
enumBodyDeclarations
: ';' classBodyDeclaration*
;
interfaceDeclaration
: INTERFACE identifier genericDeclarationList? (EXTENDS typeList)? (PERMITS typeList)? interfaceBody
;
classBody
: '{' classBodyDeclaration* '}'
;
interfaceBody
: '{' interfaceBodyDeclaration* '}'
;
classBodyDeclaration
: ';' # emptyclassbody
| STATIC? block # classblock
| modifier* memberDeclaration # memberdecl
;
memberDeclaration
: classOrInterface # memberclassorinterface
| fieldDeclaration # memberfield
| method # membermethod
| constructor # memberconstructor
;
method
: methodDeclaration # methoddecl
| genericMethodDeclaration # genericmethod
;
/* We use rule this even for void methods which cannot have [] after parameters.
This simplifies grammar and we can consider void to be a type, which
renders the [] matching as a context-sensitive issue or a semantic check
for invalid return type after parsing.
*/
methodDeclaration
: methodHeader
(THROWS exceptionList)?
methodBody
;
methodHeader
: refType? identifier formalParameters ('[' ']')*
;
methodBody
: block # methodblock
| ';' # emptymethod
;
refType
: typeType # refType2
| VOID # refvoid
;
genericMethodDeclaration
: genericDeclarationList methodDeclaration
;
constructor
: genericConstructorDeclaration # genericconstructor
| constructorDeclaration # constructordecl
;
genericConstructorDeclaration
: genericDeclarationList constructorDeclaration
;
constructorDeclaration
: identifier formalParameters (THROWS exceptionList)? constructorBody=block
;
fieldDeclaration
: typeType? variableDeclarators ';'
;
interfaceBodyDeclaration
: modifier* interfaceMemberDeclaration # interfacemember
| ';' # emptyinterface
;
interfaceMemberDeclaration
: constDeclaration # interfaceconst
| interfaceMethodDeclaration # interfacemethod
| genericInterfaceMethodDeclaration # genericinterfacemethod
| classOrInterface # subclassorinterface
;
constDeclaration
: typeType? constantDeclarator (',' constantDeclarator)* ';'
;
constantDeclarator
: identifier ('[' ']')* '=' variableInitializer
;
// Early versions of Java allows brackets after the method name, eg.
// public int[] return2DArray() [] { ... }
// is the same as
// public int[][] return2DArray() { ... }
interfaceMethodDeclaration
: interfaceMethodModifier* interfaceCommonBodyDeclaration
;
// Java8
interfaceMethodModifier
: annotation
| PUBLIC
| ABSTRACT
| DEFAULT
| STATIC
| STRICTFP
;
genericInterfaceMethodDeclaration
: interfaceMethodModifier* genericDeclarationList interfaceCommonBodyDeclaration
;
interfaceCommonBodyDeclaration
: annotation* refType? identifier formalParameters ('[' ']')* (THROWS exceptionList)? methodBody
;
variableDeclarators
: variableDeclarator (',' variableDeclarator)*
;
variableDeclarator
: variableDeclaratorId ('=' variableInitializer)?
;
variableDeclaratorId
: identifier ('[' ']')*
;
variableInitializer
: arrayInitializer
| expression
;
arrayInitializer
: '{' (variableInitializer (',' variableInitializer)* (',')? )? '}'
;
classOrInterfaceType
: (identifier typeArguments? '.')* typeIdentifier typeArguments?
;
typeArgument
: typeType
| wildcardType
;
wildcardType
: annotation* '?' (extendsWildcardType | superWildcardType)?
;
extendsWildcardType
: EXTENDS typeType
;
superWildcardType
: SUPER typeType
;
qualifiedNameList
: qualifiedName (',' qualifiedName)*
;
exceptionList
: qualifiedNameList
;
formalParameters
: '(' ( receiverParameter?
| receiverParameter (',' formalParameterList)?
| formalParameterList?
) ')'
;
receiverParameter
: typeType? (identifier '.')* THIS
;
formalParameterList
: formalParameter (',' formalParameter)* (',' lastFormalParameter)?
| lastFormalParameter
;
formalParameter
: variableModifier* typeType? variableDeclaratorId
| pattern // Pattern matching for Methods
;
lastFormalParameter
: variableModifier* typeType? annotation* '...' variableDeclaratorId
;
// local variable type inference
lambdaLVTIList
: lambdaLVTIParameter (',' lambdaLVTIParameter)*
;
lambdaLVTIParameter
: variableModifier* VAR identifier
;
qualifiedName
: identifier ('.' identifier)*
;
literal
: integerLiteral # intLiteral
| floatLiteral # fltLiteral
| CHAR_LITERAL # charLiteral
| STRING_LITERAL # stringLiteral
| BOOL_LITERAL # boolLiteral
| NULL_LITERAL # nullLiteral
| TEXT_BLOCK # textBlock // Java17
;
integerLiteral
: DECIMAL_LITERAL
| HEX_LITERAL
| OCT_LITERAL
| BINARY_LITERAL
;
floatLiteral
: FLOAT_LITERAL
| HEX_FLOAT_LITERAL
;
// ANNOTATIONS
altAnnotationQualifiedName
: (identifier DOT)* '@' identifier
;
annotation
: ('@' qualifiedName | altAnnotationQualifiedName) ('(' ( elementValuePairs | elementValue )? ')')?
;
elementValuePairs
: elementValuePair (',' elementValuePair)*
;
elementValuePair
: identifier '=' elementValue
;
elementValue
: expression
| annotation
| elementValueArrayInitializer
;
elementValueArrayInitializer
: '{' (elementValue (',' elementValue)*)? (',')? '}'
;
annotationTypeDeclaration
: '@' INTERFACE identifier annotationTypeBody
;
annotationTypeBody
: '{' (annotationTypeElementDeclaration)* '}'
;
annotationTypeElementDeclaration
: modifier* annotationTypeElementRest
| ';' // this is not allowed by the grammar, but apparently allowed by the actual compiler
;
annotationTypeElementRest
: typeType annotationMethodOrConstantRest ';'
| classOrInterface ';'?
;
annotationMethodOrConstantRest
: annotationMethodRest
| annotationConstantRest
;
annotationMethodRest
: identifier '(' ')' defaultValue?
;
annotationConstantRest
: variableDeclarators
;
defaultValue
: DEFAULT elementValue
;
// MODULES - Java9
moduleDeclaration
: OPEN? MODULE qualifiedName moduleBody
;
moduleBody
: '{' moduleDirective* '}'
;
moduleDirective
: REQUIRES requiresModifier* qualifiedName ';'
| EXPORTS qualifiedName (TO qualifiedName)? ';'
| OPENS qualifiedName (TO qualifiedName)? ';'
| USES qualifiedName ';'
| PROVIDES qualifiedName WITH qualifiedName ';'
;
requiresModifier
: TRANSITIVE
| STATIC
;
// RECORDS - Java 17
recordDeclaration
: RECORD identifier genericDeclarationList? recordHeader
(IMPLEMENTS typeList)?
recordBody
;
recordHeader
: '(' recordComponentList? ')'
;
recordComponentList
: recordComponent (',' recordComponent)*
;
recordComponent
: typeType? identifier
;
recordBody
: '{' classBodyDeclaration* '}'
;
// STATEMENTS / BLOCKS
block
: '{' blockStatement* '}'
;
blockStatement
: localVariableDeclaration ';'
| localTypeDeclaration
| statement
;
localVariableDeclaration
: variableModifier* (VAR | typeType) variableDeclarators
;
identifier
: IDENTIFIER
| MODULE
| OPEN
| REQUIRES
| EXPORTS
| OPENS
| TO
| USES
| PROVIDES
| WITH
| TRANSITIVE
| YIELD
| SEALED
| PERMITS
| RECORD
| VAR
;
typeIdentifier // Identifiers that are not restricted for type declarations
: IDENTIFIER
| MODULE
| OPEN
| REQUIRES
| EXPORTS
| OPENS
| TO
| USES
| PROVIDES
| WITH
| TRANSITIVE
| SEALED
| PERMITS
| RECORD
;
localTypeDeclaration
: classOrInterfaceModifier*
(classDeclaration | interfaceDeclaration | recordDeclaration)
| ';'
;
statement
: blockLabel=block #blockstmt
| ASSERT expression (':' expression)? ';' #assertstmt
| IF parExpression statement (ELSE statement)? #conditionalstmt
| FOR '(' forControl ')' statement #forloop
| WHILE parExpression statement #whileloop
| DO statement WHILE parExpression ';' #dowhileloop
| TRY block (catchClause+ finallyBlock? | finallyBlock) #trycatchblock
| TRY resourceSpecification block catchClause* finallyBlock? #trycatchresource
| SWITCH parExpression '{' switchBlockStatementGroup* switchLabel* '}' #switchstmt
| SYNCHRONIZED parExpression block #synchronizedstmt
| RETURN expression? ';' #returnstmt
| THROW expression ';' #throwstmt
| BREAK identifier? ';' #breakstmt
| CONTINUE identifier? ';' #continuestmt
| YIELD expression ';' #yieldstmt // Java17
| SEMI #semistmt
| statementExpression=expression ';' #stmtexpression
| identifierLabel=identifier ':' statement #labeledstmt
;
catchClause
: CATCH '(' variableModifier* catchType? identifier ')' block
;
catchType
: qualifiedName ('|' qualifiedName)*
;
finallyBlock
: FINALLY block
;
resourceSpecification
: '(' resources ';'? ')'
;
resources
: resource (';' resource)*
;
resource
: variableModifier* ( classOrInterfaceType? variableDeclaratorId | VAR identifier ) '=' expression
| identifier
;
/** Matches cases then statements, both of which are mandatory.
* To handle empty cases at the end, we add switchLabel* to statement.
*/
switchBlockStatementGroup
: switchLabel+ blockStatement+
;
switchLabel
: CASE constantExpression=expression ':' #switchLabelConst
| CASE enumConstantName=IDENTIFIER ':' #switchLabelEnum
| CASE pattern ':' #switchLabelPattern
| DEFAULT ':' #switchLabelDefault
;
forControl
: enhancedForControl
| forInit? ';' expression? ';' forUpdate=expressionList?
;
forInit
: localVariableDeclaration
| expressionList
;
enhancedForControl
: variableModifier* (typeType? | VAR) variableDeclaratorId ':' expression
;
// EXPRESSIONS
parExpression
: '(' expression ')'
;
expressionList
: expression (',' expression)*
;
methodCall
: identifier '(' expressionList? ')'
| THIS '(' expressionList? ')'
| SUPER '(' expressionList? ')'
;
expression
: primary #primaryExpression2
| expression bop='.'
(
identifier
| methodCall
| THIS
| NEW nonWildcardTypeArguments? innerCreator
| SUPER superSuffix
| explicitGenericInvocation
) # dottedexpression
| expression '[' expression ']' #arrayaccessexpression
| methodCall #methodcallexpression
| NEW creator #newinstanceexpression
| '(' annotation* typeType ('&' typeType)* ')' expression #castexpression
| expression postfix=('++' | '--') #postfixexpression
| prefix=('+'|'-'|'++'|'--'|'~'|'!') expression #prefixexpression
| expression bop=('*'|'/'|'%') expression #mathmuldivmodexpression
| expression bop=('+'|'-') expression #mathaddsubexpression
| expression ('<' '<' | '>' '>' '>' | '>' '>') expression #shiftexpression
| expression bop=('<=' | '>=' | '>' | '<') expression #relationalexpression
| expression bop=INSTANCEOF (typeType | pattern) #instanceofexpression
| expression bop=('==' | '!=') expression #equalityexpression
| expression bop='&' expression #bitwiseandexpression
| expression bop='^' expression #bitwisexorexpression
| expression bop='|' expression #bitwiseorexpression
| expression bop='&&' expression #andexpression
| expression bop='||' expression #orexpression
| <assoc=right> expression bop='?' expression ':' expression #conditionalassignexpression
| <assoc=right> expression
bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=')
expression #assignexpression
| lambdaExpression #lambdaExpression2 // Java8
| switchExpression #switchExpression2 // Java17
// Java 8 methodReference
| expression '::' typeArguments? identifier #methodreferenceexpression
| typeType '::' (typeArguments? identifier | NEW) #methodorcreatorreferenceexpression
| classType '::' typeArguments? NEW #creatorreferenceexpression
;
// Java17
pattern
: primaryPattern #pPattern
| guardedPattern #gPattern
;
primaryPattern
: typePattern #tPattern
| recordPattern #rPattern
| '(' pattern ')' #enclosedPattern
;
recordPattern
: typeType recordStructurePattern identifier?
;
typePattern
: variableModifier* typeType identifier
;
recordStructurePattern
: '(' recordComponentPatternList? ')'
;
recordComponentPatternElement
: pattern
| identifier
;
recordComponentPatternList
: pattern (',' pattern)*
;
// Java8
lambdaExpression
: lambdaParameters '->' lambdaBody
;
// Java8
lambdaParameters
: identifier
| '(' formalParameterList? ')'
| '(' identifier (',' identifier)* ')'
| '(' lambdaLVTIList? ')'
;
// Java8
lambdaBody
: expression
| block
;
primary
: '(' expression ')' # primaryExpression
| THIS # primaryThis
| SUPER # primarySuper
| literal # primaryLiteral
| identifier # primaryIdentifier
| refType '.' CLASS # primaryClassref
| nonWildcardTypeArguments (explicitGenericInvocationSuffix | THIS arguments) # primaryInvocation
;
// Java17
switchExpression
: SWITCH parExpression '{' switchLabeledRule* '}'
;
// Java17
switchLabeledRule
: switchLabelCase switchRuleOutcome
;
switchLabelCase
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
| CASE pattern (ARROW | COLON) #labeledRulePattern
| DEFAULT (ARROW | COLON) #labeledRuleDefault
;
// Java20
guardedPattern
: primaryPattern WITH expression
;
// Java17
switchRuleOutcome
: block
| expression ';'
;
classType
: (classOrInterfaceType '.')? annotation* identifier typeArguments?
;
creator
: nonWildcardTypeArguments createdName classCreatorRest
| createdName (arrayCreatorRest | classCreatorRest)
;
createdName
: identifier typeArgumentsOrDiamond?
| primitiveType
;
innerCreator
: identifier nonWildcardTypeArgumentsOrDiamond? classCreatorRest
;
arrayCreatorRest
: '[' (']' ('[' ']')* arrayInitializer | expression ']' ('[' expression ']')* ('[' ']')*)
;
classCreatorRest
: arguments classBody?
;
explicitGenericInvocation
: nonWildcardTypeArguments explicitGenericInvocationSuffix
;
typeArgumentsOrDiamond
: '<' '>'
| typeArguments
;
nonWildcardTypeArgumentsOrDiamond
: '<' '>'
| nonWildcardTypeArguments
;
nonWildcardTypeArguments
: '<' typeList '>'
;
typeList
: typeType (',' typeType)*
;
typeType
: annotation* (classOrInterfaceType | primitiveType) (annotation* '[' ']')*
;
primitiveType
: BOOLEAN
| CHAR
| BYTE
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
;
typeArguments
: '<' typeArgument (',' typeArgument)* '>'
;
superSuffix
: arguments
| '.' typeArguments? identifier arguments?
;
explicitGenericInvocationSuffix
: SUPER superSuffix
| identifier arguments
;
arguments
: '(' expressionList? ')'
;

@ -0,0 +1,10 @@
import de.dhbwstuttgart.core.ConsoleInterface;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ConsoleInterface.main(args);
}
}

@ -0,0 +1,7 @@
package de.dhbwstuttgart.bytecode;
public class CodeGenException extends RuntimeException {
public CodeGenException(String cause) {
super(cause);
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,158 @@
package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.target.tree.TargetGeneric;
import de.dhbwstuttgart.target.tree.type.*;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.objectweb.asm.Opcodes.*;
/**
* //ToDo beschreiben
*
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public class FunNGenerator {
private static final String argumentGenericBase = "T";
private static final String returnGeneric = "R";
private static final String methodName = "apply";
private static final int bytecodeVersion = V1_8;
private static final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
private static final String objectSignature = applySignature(TargetType.Object);
private static final String VOID = "Ljava/lang/Void;";
public static class GenericParameters {
int start;
public List<TargetType> parameters = new ArrayList<>();
}
private static String applyDescriptor(TargetType type, GenericParameters gep) {
if (type == null) return VOID;
var res = "L" + type.getInternalName();
if (type instanceof TargetSpecializedType a) {
if (a.params().size() > 0) {
res += "<";
for (var param : a.params()) {
if (param instanceof TargetGenericType gp) {
gep.parameters.add(param);
res += "TT" + gep.start + ";";
gep.start += 1;
} else {
res += applyDescriptor(param, gep);
}
}
res += ">";
}
} else {
gep.parameters.add(null);
return type.toDescriptor();
}
res += ";";
return res;
}
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)); }
public static String encodeType(TargetType type) {
if (type == null) return VOID;
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
}
public static byte[] generateSuperBytecode(int numberArguments) {
StringBuilder superFunNClassSignature = new StringBuilder("<");
StringBuilder superFunNMethodSignature = new StringBuilder("(");
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
for (int currentParameter = 1; currentParameter <= numberArguments; currentParameter++){
superFunNClassSignature.append(String.format("%s%d:%s", argumentGenericBase, currentParameter, objectSignature));
superFunNMethodSignature.append(String.format("T%s;", argumentGenericBase + currentParameter));
superFunNMethodDescriptor.append(objectSignature);
}
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
System.out.println(superFunNMethodSignature);
ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor;
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
methodVisitor.visitEnd();
classWriter.visitEnd();
return classWriter.toByteArray();
}
public static String getSuperClassName(int numberArguments) {
return String.format("Fun%d$$", numberArguments);
}
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType, GenericParameters gep) {
List<TargetType> parameters = Stream
.concat(argumentTypes.stream(), Stream.of(returnType))
.toList();
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), gep));
boolean containsGeneric = false;
String genericSignature = "<";
for (var i = 0; i < gep.start; i++) {
genericSignature += String.format("T%d:%s", i, objectSignature);
containsGeneric = true;
}
genericSignature += ">";
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
System.out.println(funNClassSignature.toString());
ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, new String[]{getSuperClassName(argumentTypes.size())});
classWriter.visitEnd();
return classWriter.toByteArray();
}
private static void collectGenericTypeArguments(Map<TargetGenericType, Integer> generics, TargetType typeArgument) {
if (typeArgument instanceof TargetSpecializedType specializedType) {
for (var arg : specializedType.params())
collectGenericTypeArguments(generics, arg);
} else if (typeArgument instanceof TargetGenericType genericType) {
if (generics.containsKey(genericType))
generics.put(genericType, generics.get(genericType) + 1);
else generics.put(genericType, 0);
}
}
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
return String.format("Fun%d$$%s%s",
argumentTypes.size(),
argumentTypes
.stream()
.map(FunNGenerator::encodeType)
.collect(Collectors.joining()),
encodeType(returnType));
}
public static List<TargetType> getArguments(List<TargetType> list) {
return list
.stream()
.limit(Math.max(0, list.size() - 1))
.collect(Collectors.toList());
}
public static TargetType getReturnType(List<TargetType> list) {
if(list.size() == 0)
throw new IndexOutOfBoundsException();
return list.get(list.size() - 1);
}
}

@ -0,0 +1,30 @@
package de.dhbwstuttgart.bytecode;
import org.objectweb.asm.*;
public class JavaTXSignatureAttribute extends Attribute {
public String signature;
public JavaTXSignatureAttribute() {
super("JavaTXSignature");
}
protected JavaTXSignatureAttribute(String signature) {
this();
this.signature = signature;
}
@Override
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
var data = new byte[length];
System.arraycopy(classReader.b, offset, data, 0, length);
var constantPoolOffset = data[0] << 8 | data[1];
return new JavaTXSignatureAttribute((String) classReader.readConst(constantPoolOffset, charBuffer));
}
@Override
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
var data = new ByteVector();
data.putShort(classWriter.newConst(this.signature));
return data;
}
}

@ -0,0 +1,45 @@
package de.dhbwstuttgart.core;
import java.io.File;
import java.io.IOException;
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{
System.out.println(arg);
input.add(new File(arg));
}
}
JavaTXCompiler compiler = new JavaTXCompiler(input, classpath);
//compiler.typeInference();
compiler.generateBytecode(outputPath);
}
}

@ -0,0 +1,9 @@
package de.dhbwstuttgart.core;
import org.antlr.v4.runtime.Token;
public interface IItemWithOffset
{
Token getOffset();
}

@ -0,0 +1,828 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.bytecode.Codegen;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.environment.DirectoryClassLoader;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
import de.dhbwstuttgart.target.generate.GenericsResult;
import de.dhbwstuttgart.target.tree.expression.TargetBinaryOp;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Array;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler {
// public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment;
Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
private final DirectoryClassLoader classLoader;
private final List<File> classPath;
public DirectoryClassLoader getClassLoader() {
return classLoader;
}
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null);
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile);
this.log = log;
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null);
}
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
if (contextPath == null || contextPath.isEmpty()) {
// When no contextPaths are given, the working directory is the sources root
contextPath = Lists.newArrayList(new File(System.getProperty("user.dir")));
}
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
environment = new CompilationEnvironment(sources);
classPath = contextPath;
for (File s : sources) {
parse(s);
}
// INSTANCE = this;
}
private void addSourceFile(File file, SourceFile sf) {
sourceFiles.put(file, sf);
}
public ClassOrInterface getClass(JavaClassName name) {
for (var sf : sourceFiles.values()) {
for (var clazz : sf.KlassenVektor) {
if (clazz.getClassName().equals(name)) return clazz;
}
}
try {
var clazz = classLoader.loadClass(name.toString());
if (clazz != null)
return ASTFactory.createClass(clazz);
} catch (ClassNotFoundException ignored) {}
return null;
}
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
Set<ClassOrInterface> allClasses = new HashSet<>();// environment.getAllAvailableClasses();
ClassOrInterface objectClass = ASTFactory.createClass(classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : sourceFiles.entrySet()) {
var importedClasses = new ArrayList<ClassOrInterface>();
for (JavaClassName name : source.getValue().getImports()) {
importedClasses.addAll(getAvailableClasses(name));
}
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), this)) {
ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass);
}
source.getValue().availableClasses.addAll(importedClasses);
}
for (File f : this.sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f);
SourceFile sf_new = new SourceFile(sf.getPkgName(), sf.KlassenVektor.stream().map(cl -> new ClassOrInterface(cl)).collect(Collectors.toCollection(ArrayList::new)), sf.imports);
// sf enthaelt neues Source-File, neue Klassen-Objekte und neue
// ArrayListen-Objekte fuer Fields, Construktoren und Methoden
// Alle anderen Objekte werden nur kopiert.
sf_new.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, sf.availableClasses, objectClass));
allClasses.addAll(sf_new.getClasses());
}
TYPE ty = new TYPE(sourceFiles.values(), allClasses);
return ty.getConstraints();
}
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
if (!cl.areMethodsAdded()) {
ClassOrInterface superclass = null;
Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) {
superclass = optSuperclass.get();
} else {
optSuperclass = sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) {
superclass = optSuperclass.get();
addMethods(sf, superclass, importedClasses, objectClass);
} else {
try {
var className = cl.getSuperClass().getName().toString();
superclass = ASTFactory.createClass(classLoader.loadClass(className));
} catch (ClassNotFoundException ignored) {}
// throw new ClassNotFoundException("");
}
}
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next());
}
Iterator<Method> methodIt = superclass.getMethods().iterator();
// TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert
// werden
while (methodIt.hasNext()) {
Method m = methodIt.next();
ParameterList newParaList = new ParameterList(m.getParameterList().getFormalparalist().stream().map(fp -> fp.withType(fp.getType().acceptTV(new TypeExchanger(gtvs)))).collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
// new GenericDeclarationList(newGenericsList,
// ((GenericDeclarationList)m.getGenerics()).getOffset()),
(GenericDeclarationList) m.getGenerics(), m.getOffset(), true));
}
}
cl.setMethodsAdded();
}
private List<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
Set<ClassOrInterface> allClasses = new HashSet<>();
if (loadJavaTXClass(name)) {
var file = findFileForClass(name);
var sf = sourceFiles.get(file);
if (sf != null) allClasses.addAll(sf.KlassenVektor);
} else {
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
allClasses.add(importedClass);
}
return new ArrayList<>(allClasses);
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
// hinzugefuegt werden
// List<ClassOrInterface> allClasses = new
// ArrayList<>();//environment.getAllAvailableClasses();
Set<ClassOrInterface> allClasses = new HashSet<>();
for (JavaClassName name : forSourceFile.getImports()) {
allClasses.addAll(getAvailableClasses(name));
}
return new ArrayList<>(allClasses);
}
/*
* public List<ResultSet> typeInferenceOld() throws ClassNotFoundException { List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(sf.getClasses()); }
*
* final ConstraintSet<Pair> cons = getConstraints();
*
* FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); System.out.println(finiteClosure); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
*
* TypeUnify unify = new TypeUnify(); Set<Set<UnifyPair>> results = new HashSet<>(); try { File logPath = new File(System.getProperty("user.dir")+"/target/logFiles/"); logPath.mkdirs(); FileWriter logFile = new FileWriter(new File(logPath, "log")); logFile.write("FC:\\" + finiteClosure.toString()+"\n"); for(SourceFile sf : this.sourceFiles.values()) { logFile.write(ASTTypePrinter.print(sf)); } logFile.flush(); Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct(); for
* (List<Constraint<UnifyPair>> xCons : cardProd ){ Set<UnifyPair> xConsSet = new HashSet<>(); for (Constraint<UnifyPair> constraint : xCons) { xConsSet.addAll(constraint); } //.collect(Collectors.toCollection(ArrayList::new)))) System.out.println(xConsSet); 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);
*
* xConsSet = xConsSet.stream().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 }).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; } ) .collect(Collectors.toCollection(HashSet::new)); varianceInheritance(xConsSet); Set<Set<UnifyPair>> result =
* unify.unifySequential(xConsSet, finiteClosure, logFile, log); //Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); System.out.println("RESULT: " + result); logFile.write("RES: " + result.toString()+"\n"); logFile.flush(); results.addAll(result); }
*
* results = results.stream().map(x -> { Optional<Set<UnifyPair>> res = new RuleSet().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().applyTypeUnificationRules(res.get(), finiteClosure); } else return x; //wenn nichts
* veraendert wurde wird x zurueckgegeben }).collect(Collectors.toCollection(HashSet::new)); System.out.println("RESULT Final: " + results); logFile.write("RES_FINAL: " + results.toString()+"\n"); logFile.flush(); logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); logFile.flush(); } catch (IOException e) { e.printStackTrace(); } return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs,
* generateTPHMap(cons))))).collect(Collectors.toList()); }
*/
/**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
*
*
*/
/*
* private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType> usedTPH = new HashSet<>(); Set<PlaceholderType> phSet = eq.stream().map(x -> { Set<PlaceholderType> pair = new HashSet<>(); if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType()); return pair; }).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;});
*
* ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet); phSetVariance.removeIf(x -> (x.getVariance() == 0)); while(!phSetVariance.isEmpty()) { PlaceholderType a = phSetVariance.remove(0); usedTPH.add(a); //HashMap<PlaceholderType,Integer> ht = new HashMap<>(); //ht.put(a, a.getVariance()); Set<UnifyPair> eq1 = new HashSet<>(eq); eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a))); eq1.stream().forEach(x -> {
* x.getRhsType().accept(new distributeVariance(), a.getVariance());}); eq1 = new HashSet<>(eq); eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a))); eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(), a.getVariance());}); phSetVariance = new ArrayList<>(phSet); phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); } }
*/
public UnifyResultModel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile) throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : this.sourceFiles.entrySet()) {
SourceFile sf = source.getValue();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
}
final ConstraintSet<Pair> cons = getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener);
try {
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader());
System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
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;
};
logFile.write(unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars);
logFile.write(unifyCons.toString());
TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n");
for (SourceFile sf : this.sourceFiles.values()) {
logFile.write(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
});
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");
}
return urm;
}
public List<ResultSet> typeInference() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (Entry<File, SourceFile> source : this.sourceFiles.entrySet()) {
SourceFile sf = source.getValue();
allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses());
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList());
for (var clazz : newClasses) {
// Don't load classes that get recompiled
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
continue;
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
allClasses.add(clazz);
}
}
final ConstraintSet<Pair> cons = getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>();
try {
var logFolder = new File(System.getProperty("user.dir") + "/logFiles/");
if (log) logFolder.mkdirs();
Writer logFile = log ? new FileWriter(new File(logFolder, "log_" + sourceFiles.keySet().iterator().next().getName())) : new OutputStreamWriter(new NullOutputStream());
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
System.out.println("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;
};
logFile.write("Unify:" + unifyCons.toString());
System.out.println("Unify:" + unifyCons.toString());
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");
for (SourceFile sf : this.sourceFiles.values()) {
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> 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 (resultmodel) {
/* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
System.out.println("RESULT Final: " + li.getResults());
System.out.println("Constraints for Generated Generics: " + " ???");
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFile.flush();
return li.getResults();
}
/* UnifyResultModel End */
else {
// Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
// 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 = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().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().applyTypeUnificationRules(res.get(), finiteClosure);
} else
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).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) {
System.err.println("kein LogFile");
}
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
}
/**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
*
*
*/
private Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) {
Set<UnifyPair> eq = cons.getAll();
Set<PlaceholderType> usedTPH = new HashSet<>();
Set<PlaceholderType> phSet = eq.stream().map(x -> {
Set<PlaceholderType> pair = new HashSet<>();
if (x.getLhsType() instanceof PlaceholderType)
pair.add((PlaceholderType) x.getLhsType());
if (x.getRhsType() instanceof PlaceholderType)
pair.add((PlaceholderType) x.getRhsType());
return pair;
}).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b);
return a;
}, (c, d) -> {
c.addAll(d);
return c;
});
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0));
while (!phSetVariance.isEmpty()) {
PlaceholderType a = phSetVariance.remove(0);
usedTPH.add(a);
// HashMap<PlaceholderType,Integer> ht = new HashMap<>();
// ht.put(a, a.getVariance());
// ConstraintSet<UnifyPair> eq1 = cons;
// eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType &&
// ((PlaceholderType)x.getLhsType()).equals(a)));
// durch if-Abfrage im foreach geloest
cons.forEach(x -> {
if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) {
x.getRhsType().accept(new distributeVariance(), a.getVariance());
}
});
// ` eq1 = new HashSet<>(eq);
// eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType &&
// ((PlaceholderType)x.getRhsType()).equals(a)));
// durch if-Abfrage im foreach geloest
cons.forEach(x -> {
if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) {
x.getLhsType().accept(new distributeVariance(), a.getVariance());
}
});
phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue
// TPHs mit Variancen dazugekommen sein PL 2018-11-07
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
}
return usedTPH;
}
public final JavaClassRegistry classRegistry = new JavaClassRegistry();
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
SourceFileContext tree = JavaTXParser.parse(sourceFile);
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null), sourceFile.getName());
var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(sourceFile, sf);
generator.convert(classes, tree, environment.packageCrawler);
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 boolean loadJavaTXClass(JavaClassName name) {
var file = findFileForClass(name);
if (file != null) {
if (classRegistry.contains(name)) return true;
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(generator.pkgName, classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
return true;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return false;
}
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 {
generateBytecode((File) null);
}
/**
* @param path - can be null, then class file output is in the same directory as the parsed source files
*/
public void generateBytecode(String path) throws ClassNotFoundException, IOException {
if (path != null)
generateBytecode(new File(path));
else
generateBytecode();
}
/**
* @param path - output-Directory can be null, then class file output is in the same directory as the parsed source files
*/
public void generateBytecode(File path) throws ClassNotFoundException, IOException {
List<ResultSet> typeinferenceResult = this.typeInference();
generateBytecode(path, typeinferenceResult);
}
private Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {
return generatedGenerics;
}
/**
* @param outputPath - can be null, then class file output is in the same directory as the parsed source files
* @param typeinferenceResult
* @throws IOException
*/
public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult) throws IOException {
for (File f : sourceFiles.keySet()) {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f);
File path;
if (outputPath == null) {
path = f.getParentFile(); // Set path to path of the parsed .jav file
} else {
path = new File(outputPath, sf.getPkgName().replace(".", "/")); // add package path to root path
}
var generatedClasses = generateBytecode(sf, typeinferenceResult);
writeClassFile(generatedClasses, path);
}
}
public synchronized Map<JavaClassName, byte[]> generateBytecode(SourceFile sf, List<ResultSet> typeInferenceResult) {
var converter = new ASTToTargetAST(this, typeInferenceResult, sf, classLoader);
var generatedClasses = new HashMap<JavaClassName, byte[]>();
for (var clazz : sf.getClasses()) {
var codegen = new Codegen(converter.convert(clazz), this);
var code = codegen.generate();
generatedClasses.put(clazz.getClassName(), code);
converter.auxiliaries.forEach((name, source) -> {
generatedClasses.put(new JavaClassName(name), source);
});
}
generatedGenerics.put(sf, converter.javaGenerics());
return generatedClasses;
}
public synchronized void writeClassFile(Map<JavaClassName, byte[]> classFiles, File path) throws IOException {
FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ...");
// output = new FileOutputStream(new File(System.getProperty("user.dir") +
// "/testBytecode/generatedBC/" +name+".class"));
File outputFile = new File(path, name.getClassName() + ".class");
outputFile.getAbsoluteFile().getParentFile().mkdirs();
output = new FileOutputStream(outputFile);
output.write(bytecode);
output.close();
System.out.println(name + ".class file generated");
}
}
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchanger(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) {
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
return ret;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
return typePlaceholder; // TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert
// werden.
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
return ret;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if (!gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
return gtvs.get(genericRefType.getParsedName());
}
}
}

@ -0,0 +1,13 @@
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);
}
}

@ -0,0 +1,112 @@
package de.dhbwstuttgart.environment;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.parser.scope.GatherNames;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
/**
* Stellt die Java-Environment dar und speichert alle Binarys, Librarys und Sourcefiles im zu kompilierenden Projekt Sie erstellt anhand dieser Informationen die JavaClassNameRegistry
*
* TODO: Zur Initialisierung der CompilationEnvironment sollten alle SourceFiles mit ANTLR geparst werden und alle Klassen Generics und Typen herausgefunden werden
*/
public class CompilationEnvironment {
private final List<URL> librarys;
private final List<File> sourceFiles;
public final PackageCrawler packageCrawler;
/**
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<74>lt automatisch die Java Standard Library
*
* @param sourceFiles die zu kompilierenden Dateien
*/
public CompilationEnvironment(List<File> sourceFiles) {
/**
* Java 9 bringt einige Änderungen am Classloader So funktioniert der BootClassLoader nicht mehr. hier gibts ein paar Quellen zum nachlesen: http://java9.wtf/class-loading/ https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9
*
*/
// String bootClassPath = System.getProperty("sun.boot.class.path");
// DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader();
String bootClassPath = System.getProperty("java.class.path");
librarys = new ArrayList<>();
for (String path : bootClassPath.split(File.pathSeparator)) {
try {
librarys.add(new URL("file:" + path));
} catch (MalformedURLException e) {
new DebugException("Fehler im Classpath auf diesem System");
}
}
// URLClassLoader loader = new URLClassLoader(new URL[0], cl);
// librarys = Arrays.asList(loader.getURLs());
this.sourceFiles = sourceFiles;
this.packageCrawler = new PackageCrawler(librarys);
}
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
Map<String, Integer> allNames;
if (tree instanceof SrcfileContext srcfile) {
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, compiler);
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, compiler)) {
allNames.put(c.getName(), c.getTypeParameters().length);
}
registry.addNames(allNames);
} else {
throw new NotImplementedException();
}
}
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, JavaTXCompiler compiler) throws IOException, ClassNotFoundException {
ClassLoader classLoader = compiler.getClassLoader();
List<Class> ret = new ArrayList<>();
// Set classLoader to include default package for this specific source file
File dir = sourceFile.getAbsoluteFile().getParentFile();
String dirPath = dir.toString() + "/";
if (packageName.length() > 0)
dirPath = dirPath.substring(0, dirPath.length() - packageName.length() - 1);
String path = dirPath;
ArrayList<File> defaultPath = Lists.newArrayList(new File(path));
classLoader = new DirectoryClassLoader(defaultPath, classLoader);
// Gather all names in the default package for this source file (classes that are imported by default)
File[] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
if (files != null)
for (File classFile : files) {
String className = classFile.getName().substring(0, classFile.getName().length() - 6);
if (className.matches("Fun\\d+\\$\\$.*"))
continue;
ret.add(classLoader.loadClass(packageName + className));
}
return ret;
}
private static String getPackageName(SrcfileContext forTree) {
String packageName = "";
if (forTree.packageDeclaration() != null && !forTree.packageDeclaration().qualifiedName().identifier().isEmpty())
packageName = forTree.packageDeclaration().qualifiedName().getText();
return packageName;
}
public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>();
for (Class c : new PackageCrawler(librarys).getAllAvailableClasses()) {
ret.add(ASTFactory.createClass(c));
}
return ret;
}
}

@ -0,0 +1,44 @@
package de.dhbwstuttgart.environment;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
public class DirectoryClassLoader extends URLClassLoader implements IByteArrayClassLoader {
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
super(generateURLArray(dirToURL(directory)), parent);
}
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
super(directory.stream().map(DirectoryClassLoader::dirToURL).collect(Collectors.toList()).toArray(new URL[0]), parent);
}
private static URL[] generateURLArray(URL url) {
return new URL[]{url};
}
private static URL dirToURL(File url){
if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
try {
return url.toURI().toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
@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);
}
}

@ -0,0 +1,23 @@
package de.dhbwstuttgart.environment;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public interface IByteArrayClassLoader {
Class loadClass(String path) throws ClassNotFoundException;
default Class loadClass(byte[] code) {
return this._defineClass(null, code, 0, code.length);
}
default Class loadClass(Path path) throws IOException {
var code = Files.readAllBytes(path);
return this._defineClass(null, code, 0, code.length);
}
public Class<?> findClass(String name) throws ClassNotFoundException;
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
}

@ -0,0 +1,77 @@
package de.dhbwstuttgart.environment;
import java.net.URL;
import java.util.*;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import org.reflections.vfs.SystemDir;
/**
* Hilft beim Durchsuchen von Packages
* Benutzt die Reflections-Library (https://github.com/ronmamo/reflections)
* Hilfe dazu: http://stackoverflow.com/a/9571146
*/
public class PackageCrawler {
final URL[] urls;
public PackageCrawler(List<URL> urlList) {
urls = urlList.toArray(new URL[0]);
}
public Set<Class<?>> getClassesInPackage(String packageName){
/*
List<DirectoryClassLoader> classLoadersList = new LinkedList<DirectoryClassLoader>();
classLoadersList.add(Thread.currentThread().getContextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
classLoadersList.add(Thread.currentThread().getContextClassLoader().getParent());
classLoadersList.add(DirectoryClassLoader.getSystemClassLoader());
String bootClassPath = System.getProperty("sun.boot.class.path");
ArrayList<URL> urlList = new ArrayList<>();
for(String path : bootClassPath.split(";")) {
try {
urlList.add(new URL("file:"+path));
} catch (MalformedURLException e) {
new DebugException("Fehler im Classpath auf diesem System");
}
}
URL[] urls = urlList.toArray(new URL[0]);
classLoadersList.add(new URLClassLoader(urls, DirectoryClassLoader.getSystemClassLoader()));
*/
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls)
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(packageName))));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public Set<Class<?>> getAllAvailableClasses(){
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public Map<String, Integer> getClassNames(String packageName){
Map<String, Integer> nameList = new HashMap<>();
Set<Class<?>> classes = getClassesInPackage(packageName);
if(packageName.equals("java.lang") && ! classes.contains(Object.class)) {
classes.add(Object.class);
}
for(Class c : classes){
nameList.put(c.getName(), c.getTypeParameters().length);
}
return nameList;
}
}

@ -0,0 +1,8 @@
package de.dhbwstuttgart.exceptions;
public class DebugException extends RuntimeException {
public DebugException(String message) {
System.err.print(message);
}
}

@ -0,0 +1,11 @@
package de.dhbwstuttgart.exceptions;
public class NotImplementedException extends RuntimeException {
public NotImplementedException() {
}
public NotImplementedException(String string) {
super(string);
}
}

@ -0,0 +1,10 @@
package de.dhbwstuttgart.exceptions;
import org.antlr.v4.runtime.Token;
public class ParserError extends TypeinferenceException{
public ParserError(Token offset){
super("Fehler beim Parsen", offset);
}
}

@ -0,0 +1,46 @@
package de.dhbwstuttgart.exceptions;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import org.antlr.v4.runtime.Token;
/**
* Eine RuntimeException, welche bei einem Fehler während des Typinferenzalgorithmus ausgelöst wird.
* Dies wird zum Beispiel durch Programmierfehler in der Java-Eingabedatei ausgelöst.
* @author Andreas Stadelmeier, a10023
*
*/
//TODO: Diese Klasse muss von Exception erben
public class TypeinferenceException extends RuntimeException {
/**
* Das Offset im Quelltext bei dem das Problem aufgetaucht ist
*/
private Token offset;
private String message;
public TypeinferenceException(String message, SyntaxTreeNode problemSource)
{
super(message);
this.message=message;
if(problemSource == null)throw new DebugException("TypinferenzException ohne Offset: "+this.message);
this.offset=problemSource.getOffset();
}
public TypeinferenceException(String message, Token offset){
this.message=message;
this.offset = offset;
}
/**
*
* @return Der Offset an dem im Quellcode der Fehler aufgetreten ist.
*/
public Token getOffset(){
return offset;
}
public String getMessage(){
return this.message;
}
}

@ -0,0 +1,36 @@
package de.dhbwstuttgart.parser;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class JavaTXParser {
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
InputStream stream = new FileInputStream(source);
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
CharStream input = CharStreams.fromStream(stream);
Java17Lexer lexer = new Java17Lexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Java17Parser parser = new Java17Parser(tokens);
return parser.sourceFile();
/*
* SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); return generator.convert(tree);
*/
}
/*
* Für das Typsystem ist es notwendig, dass sich der Source in einer Datei befindet: public SourceFile parse(String fileContent) throws IOException, java.lang.ClassNotFoundException { return this.parse(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); }
*/
}

@ -0,0 +1,57 @@
package de.dhbwstuttgart.parser;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenSource;
public class NullToken implements Token {
@Override
public String getText() {
return "";
}
@Override
public int getType() {
return 0;
}
@Override
public int getLine() {
return 0;
}
@Override
public int getCharPositionInLine() {
return 0;
}
@Override
public int getChannel() {
return 0;
}
@Override
public int getTokenIndex() {
return 0;
}
@Override
public int getStartIndex() {
return 0;
}
@Override
public int getStopIndex() {
return 0;
}
@Override
public TokenSource getTokenSource() {
return null;
}
@Override
public CharStream getInputStream() {
return null;
}
}

@ -0,0 +1,4 @@
package de.dhbwstuttgart.parser;
public record SourceLoc(String file, int line) {
}

@ -0,0 +1,20 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
public class AssignToLocal extends AssignLeftSide {
public final LocalVar localVar;
public AssignToLocal(LocalVar leftSide) {
super(leftSide.getType(), leftSide.getOffset());
localVar = leftSide;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

@ -0,0 +1,203 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.Pattern;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.*;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.Token;
public class FCGenerator {
/**
* Baut die FiniteClosure aus availableClasses.
* Klassen welche nicht in availableClasses vorkommen werden im Java Classpath nachgeschlagen.
*
* @param availableClasses - Alle geparsten Klassen
*/
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
}
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
HashSet<Pair> pairs = new HashSet<>();
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
for(ClassOrInterface cly : availableClasses){
List<Pair> newPairs = getSuperTypes(cly, availableClasses, gtvs, classLoader);
pairs.addAll(newPairs);
//For all Functional Interfaces FI: FunN$$<... args auf dem Functional Interface ...> <. FI is added to FC
if (isFunctionalInterface(cly)) {
pairs.add(genImplFunType(cly, newPairs.get(0).TA1, gtvs));
}
}
return pairs;
}
private static Boolean isFunctionalInterface(ClassOrInterface cly) {
return (cly.isInterface() && (cly.isFunctionalInterface() || cly.getMethods().size() == 1));
}
private static Pair genImplFunType(ClassOrInterface cly, RefTypeOrTPHOrWildcardOrGeneric fIType, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
for(Method m : cly.getMethods()) {
if (!java.lang.reflect.Modifier.isAbstract(m.modifier))
continue;
List<RefTypeOrTPHOrWildcardOrGeneric> tl =
(m.getParameterList().getFormalparalist()
.stream().map(p -> p.getType().acceptTV(new TypeExchanger(gtvs)))
.collect(Collectors.toList()));
tl.add(m.getReturnType().acceptTV(new TypeExchanger(gtvs)));
return new Pair(new RefType(new JavaClassName("Fun" + (tl.size()-1) + "$$"), tl, new NullToken()),
fIType, PairOperator.SMALLER);
}
return null; //kann nicht passieren, da die Methode nur aufgerufen wird wenn cl Functional Interface ist
}
/**
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
* Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH
* @param forType
* @return
*/
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, ClassLoader classLoader) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader);
}
/**
*
* @param forType
* @param availableClasses
* @param gtvs
* @return
* @throws ClassNotFoundException
*/
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs, ClassLoader classLoader) throws ClassNotFoundException {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
//Die GTVs, die in forType hinzukommen:
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
//Generics mit gleichem Namen müssen den selben TPH bekommen
for(GenericTypeVar gtv : forType.getGenerics()){
if(!gtvs.containsKey(gtv.getName())){
TypePlaceholder replacePlaceholder = TypePlaceholder.fresh(new NullToken());
gtvs.put(gtv.getName(), replacePlaceholder);
newGTVs.put(gtv.getName(), replacePlaceholder);
}
params.add(gtvs.get(gtv.getName()));
}
List<RefType> superClasses = new ArrayList<>();
superClasses.add(forType.getSuperClass());
superClasses.addAll(forType.getSuperInterfaces());
List<Pair> retList = new ArrayList<>();
for(RefType superType : superClasses){
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> superType.getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception
{
superClass = ASTFactory.createClass(classLoader.loadClass(superType.getName().toString()));
}else{
superClass = hasSuperclass.get();
}
/*
Die Parameter der superklasse müssen jetzt nach den Angaben in der Subklasse
modifiziert werden
Beispie: Matrix<A> extends Vector<Vector<A>>
Den ersten Parameter mit Vector<A> austauschen und dort alle Generics zu den Typplaceholdern in gtvs austauschen
*/
//Hier vermerken, welche Typen in der Superklasse ausgetauscht werden müssen
Iterator<GenericTypeVar> itGenParams = superClass.getGenerics().iterator();
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itSetParams = superType.getParaList().iterator();
while(itSetParams.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next();
//In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen:
RefTypeOrTPHOrWildcardOrGeneric setSetType = setType.acceptTV(new TypeExchanger(gtvs));
newGTVs.put(itGenParams.next().getName(), setSetType);
}
//Für den superType kann man nun zum Austauschen der Generics wieder die gtvs nehmen:
//Die newGTVs sind nur für den superClass ClassOrInterface welches möglicherweise per reflection geladen wurde abgestimmt
RefTypeOrTPHOrWildcardOrGeneric superRefType = superType.acceptTV(new TypeExchanger(gtvs));
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken());
RefTypeOrTPHOrWildcardOrGeneric t2 = superRefType;
Pair ret = new Pair(t1, t2, PairOperator.SMALLER);
List<Pair> superTypes;
//Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse:
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader);
}
retList.add(ret);
retList.addAll(superTypes);
}
return retList;
}
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchanger(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) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
return gtvs.get(genericRefType.getParsedName());
}
}
}

@ -0,0 +1,6 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public record FieldEntry(String name, RefTypeOrTPHOrWildcardOrGeneric type, int modifiers) {
}

@ -0,0 +1,14 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.scope.JavaClassName;
public class GenericContext {
private final String parentMethod;
private final JavaClassName parentClass;
public GenericContext(JavaClassName parentClass, String parentMethod) {
if(parentMethod == null)parentMethod = "";
this.parentClass = parentClass;
this.parentMethod = parentMethod;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,46 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.statement.*;
import java.util.List;
public class SyntacticSugar {
public static List<Statement> addTrailingReturn(List<Statement> statements) {
if (statements.size() != 0) {
Statement lastStmt = statements.get(statements.size() - 1);
ReturnFinder hasReturn = new ReturnFinder();
lastStmt.accept(hasReturn);
if (hasReturn.hasReturn)
return statements;
}
statements.add(new ReturnVoid(new NullToken()));
return statements;
}
private static class ReturnFinder extends AbstractASTWalker {
public boolean hasReturn = false;
@Override
public void visit(Return aReturn) {
hasReturn = true;
}
@Override
public void visit(ReturnVoid aReturn) {
hasReturn = true;
}
}
private static boolean hasReturn(Block block) {
for (Statement s : block.getStatements())
if (s instanceof Return)
return true;
return false;
}
}

@ -0,0 +1,640 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.Record;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.antlr.v4.runtime.CommonToken;
import org.antlr.v4.runtime.Token;
import com.google.common.graph.ElementOrder.Type;
import de.dhbwstuttgart.environment.PackageCrawler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceTypeContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ConstructorDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ConstructordeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.EmptymethodContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericConstructorDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericDeclarationListContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericInterfaceMethodDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericconstructorContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericinterfacemethodContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericmethodContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceCommonBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceMethodDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceMethodModifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceconstContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacemethodContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberconstructorContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberfieldContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MembermethodContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodBodyContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodHeaderContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodblockContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MethoddeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ModifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordComponentContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RecordDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.RefType2Context;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypeArgumentsContext;
import de.dhbwstuttgart.parser.scope.GatherNames;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.constraints.GenericsResolver;
import javassist.compiler.SyntaxError;
import javax.swing.text.html.Option;
public class SyntaxTreeGenerator {
private JavaClassRegistry reg;
private final GenericsRegistry globalGenerics;
public String pkgName = "";
public Set<JavaClassName> imports = new HashSet<>();
HashMap<String, Integer> allmodifiers = new HashMap<>();
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
// bekommen
private final Map<String, FieldEntry> fields = new HashMap<>();
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
List<Statement> fieldInitializations = new ArrayList<>();
List<Statement> staticFieldInitializations = new ArrayList<>();
private final JavaTXCompiler compiler;
private RefType superClass;
public final String fileName;
public SyntaxTreeGenerator(JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry globalGenerics, String fileName) {
// Die Generics müssen während des Bauens des AST erstellt werden,
// da diese mit der Methode oder Klasse, in welcher sie deklariert werden
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer
// globalen Datenbank benötigt.
this.globalGenerics = globalGenerics;
this.reg = reg;
this.allmodifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC);
this.allmodifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE);
this.allmodifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED);
this.allmodifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT);
this.allmodifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC);
this.allmodifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT);
this.allmodifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL);
this.allmodifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT);
this.allmodifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE);
this.allmodifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED);
this.allmodifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE);
this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE);
this.allmodifiers.put("sealed", 4096);
this.allmodifiers.put("non-sealed", 8192);
this.allmodifiers.put("default", 16384);
this.allmodifiers.put("strictfp", 32768);
this.compiler = compiler;
this.fileName = fileName;
}
public JavaClassRegistry getReg() {
return this.reg;
}
public String convertQualifiedName(Java17Parser.QualifiedNameContext ctx) {
/*
* String ret = ""; for (Java17Parser.IdentifierContext ident : ctx.identifier()) { ret += ident.getText(); if (ctx.identifier().iterator().hasNext()) { ret += '.'; } }
*/
return ctx.getText();
}
public void convert(List<ClassOrInterface> classes, Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException {
SrcfileContext srcfile;
if (ctx instanceof Java17Parser.SrcfileContext) {
srcfile = (SrcfileContext) ctx;
} else {
return;
}
if (srcfile.packageDeclaration() != null)
this.pkgName = convert(srcfile.packageDeclaration());
Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, compiler);
this.imports.addAll(imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()));
for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) {
ClassorinterfacedeclContext clsoif;
if (type instanceof NoclassorinterfaceContext) {
continue;
} else {
clsoif = (ClassorinterfacedeclContext) type;
}
ClassOrInterface newClass;
int modifiers = 0;
if (!clsoif.classOrInterfaceModifier().isEmpty()) {
for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) {
modifiers += allmodifiers.get(mod.getText());
}
}
fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden
staticFieldInitializations = new ArrayList<>();
if (!Objects.isNull(clsoif.classDeclaration())) {
newClass = convertClass(clsoif.classDeclaration(), modifiers);
} else if (!Objects.isNull(clsoif.interfaceDeclaration())) {
newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers);
} else if (!Objects.isNull(clsoif.recordDeclaration())) {
newClass = convertRecord(clsoif.recordDeclaration(), modifiers);
} else {
throw new NotImplementedException();
}
classes.add(newClass);
}
if (classes.isEmpty()) {
throw new NotImplementedException("SourceFile enthält keine Klassen");
}
}
private String convert(Java17Parser.PackageDeclarationContext ctx) {
return convertQualifiedName(ctx.qualifiedName());
}
private ClassOrInterface convertClass(Java17Parser.ClassDeclarationContext ctx, int modifiers) {
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + ctx.identifier().getText();
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor?
throw new TypeinferenceException("Name " + className + " bereits vorhanden in " + reg.getName(className).toString(), ctx.getStart());
}
GenericsRegistry generics = createGenerics(ctx.genericDeclarationList(), name, "", reg, new GenericsRegistry(globalGenerics));
Token offset = ctx.getStart();
GenericDeclarationList genericClassParameters;
if (ctx.genericDeclarationList() == null) {
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.classBody().getStart());
} else {
genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics);
}
RefType superClass;
if (ctx.EXTENDS() != null) {
superClass = convertSuperType(ctx.typeType());
} else {
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
}
this.superClass = superClass;
List<Field> fielddecl = new ArrayList<>();
List<Method> methods = new ArrayList<>();
List<Constructor> constructors = new ArrayList<>();
Boolean isInterface = false;
Boolean isFunctionalInterface = false;
List<RefType> implementedInterfaces = new ArrayList<>();
List<RefType> permittedSubtypes = new ArrayList<>();
for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) {
convert(clsbodydecl, fielddecl, constructors, methods, name, superClass, generics);
}
if (constructors.isEmpty()) {
constructors.add(generateStandardConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset));
}
if (ctx.IMPLEMENTS() != null) {
implementedInterfaces.addAll(convert(ctx.typeList(0), generics));
}
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");
}
}
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset));
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, fileName);
}
private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) {
this.superClass = new RefType(new JavaClassName("java.lang.Record"), new NullToken());
String identifier = recordDeclaration.identifier().getText();
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + identifier;
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
Token offset = recordDeclaration.getStart();
GenericsRegistry generics = createGenerics(recordDeclaration.genericDeclarationList(), name, "", reg, new GenericsRegistry(globalGenerics));
if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor?
throw new TypeinferenceException("Name " + className + " bereits vorhanden in " + reg.getName(className).toString(), recordDeclaration.getStart());
}
GenericDeclarationList genericClassParameters;
if (recordDeclaration.genericDeclarationList() == null) {
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), recordDeclaration.recordBody().getStart());
} else {
genericClassParameters = TypeGenerator.convert(recordDeclaration.genericDeclarationList(), name, "", reg, generics);
}
RefType superClass = new RefType(ASTFactory.createClass(java.lang.Record.class).getClassName(), offset);
List<Field> fielddecl = new ArrayList<>();
List<Method> methods = new ArrayList<>();
List<Constructor> constructors = new ArrayList<>();
Boolean isInterface = false;
List<RefType> implementedInterfaces = new ArrayList<>();
List<Pattern> constructorParameters = new ArrayList<>();
List<Statement> constructorStatements = new ArrayList<>();
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
String fieldname = component.identifier().getText();
Token fieldoffset = component.getStart();
RefTypeOrTPHOrWildcardOrGeneric fieldtype = null;
if (Objects.isNull(component.typeType())) {
fieldtype = TypePlaceholder.fresh(offset);
} else {
fieldtype = TypeGenerator.convert(component.typeType(), reg, generics);
}
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), 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));
}
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), genericClassParameters, offset);
Constructor implicitConstructor = new Constructor(allmodifiers.get("public"), identifier, classType, new ParameterList(constructorParameters, offset), prepareBlock(new Block(constructorStatements, offset), superClass), genericClassParameters, offset);
//Optional<Constructor> initializations = Optional.of(implicitConstructor);
constructors.add(implicitConstructor);
for (ClassBodyDeclarationContext bodyDeclaration : recordDeclaration.recordBody().classBodyDeclaration()) {
convert(bodyDeclaration, fielddecl, constructors, methods, name, superClass, generics);
}
if (!Objects.isNull(recordDeclaration.IMPLEMENTS())) {
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
}
var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new Record(modifiers, name, fielddecl, Optional.empty(), staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset, fileName);
}
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
MemberdeclContext member;
if (classBody instanceof MemberdeclContext) {
member = (MemberdeclContext) classBody;
Integer membermodifiers = 0;
for (ModifierContext mod : member.modifier()) {
if (mod.classOrInterfaceModifier() != null && mod.classOrInterfaceModifier().annotation() != null)
continue; // TODO don't eat annotations
membermodifiers += allmodifiers.get(mod.getText());
}
switch (member.memberDeclaration()) {
case MemberclassorinterfaceContext memberclsoif: {
break;
}
case MemberfieldContext memberfield: {
fields.addAll(convert(memberfield.fieldDeclaration(), membermodifiers, generics));
break;
}
case MembermethodContext membermethod: {
Method convertedMethod = convert(membermodifiers, membermethod.method(), name, superClass, generics);
if (convertedMethod instanceof Constructor constructor) {
constructors.add(constructor);
} else {
methods.add(convertedMethod);
}
break;
}
case MemberconstructorContext memberconstructor: {
constructors.add(convert(membermodifiers, memberconstructor.constructor(), name, superClass, generics));
break;
}
default:
break;
}
} else if (classBody instanceof Java17Parser.ClassblockContext ctx && ctx.STATIC() != null) {
// Static blocks
var stmtgen = new StatementGenerator(superClass, compiler, reg, generics, this.fields, new HashMap<>());
var block = stmtgen.convert(((Java17Parser.ClassblockContext) classBody).block(), false);
staticFieldInitializations.addAll(block.statements);
}
}
private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext ctx, int modifiers) {
this.superClass = new RefType(new JavaClassName("java.lang.Object"), new NullToken());
String className = this.pkgName.length() > 0 ? this.pkgName + "." : "" + ctx.identifier().getText();
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor?
throw new TypeinferenceException("Name " + className + " bereits vorhanden in " + reg.getName(className).toString(), ctx.getStart());
}
if (!Modifier.isInterface(modifiers))
modifiers += Modifier.INTERFACE;
GenericsRegistry generics = createGenerics(ctx.genericDeclarationList(), name, "", reg, new GenericsRegistry(globalGenerics));
GenericDeclarationList genericParams;
if (!Objects.isNull(ctx.genericDeclarationList())) {
genericParams = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics);
} else {
genericParams = createEmptyGenericDeclarationList(ctx.identifier().getStart());
}
RefType superClass = ASTFactory.createObjectType();
List<Field> fields = new ArrayList<>();
List<Method> methods = new ArrayList<>();
for (InterfaceBodyDeclarationContext interfacebody : ctx.interfaceBody().interfaceBodyDeclaration()) {
if (interfacebody instanceof Java17Parser.EmptyinterfaceContext) {
continue;
} else {
InterfacememberContext interfacemember = (InterfacememberContext) interfacebody;
int membermodifiers = 0;
for (ModifierContext mod : interfacemember.modifier()) {
membermodifiers += allmodifiers.get(mod.getText());
}
int methodmodifiers = membermodifiers;
switch (interfacemember.interfaceMemberDeclaration()) {
case InterfaceconstContext constant:
fields.add(convert(constant));
break;
case InterfacemethodContext method:
InterfaceMethodDeclarationContext declaration = method.interfaceMethodDeclaration();
for (InterfaceMethodModifierContext mod : declaration.interfaceMethodModifier()) {
methodmodifiers += allmodifiers.get(mod.getText());
}
InterfaceCommonBodyDeclarationContext commonbody = declaration.interfaceCommonBodyDeclaration();
methods.add(convert(methodmodifiers, commonbody, new GenericDeclarationList(new ArrayList<>(), commonbody.getStart()), generics));
break;
case GenericinterfacemethodContext genericmethod:
GenericInterfaceMethodDeclarationContext genericdeclaration = genericmethod.genericInterfaceMethodDeclaration();
int genericmethodmodifiers = 0;
for (InterfaceMethodModifierContext mod : genericdeclaration.interfaceMethodModifier()) {
genericmethodmodifiers += allmodifiers.get(mod.getText());
}
commonbody = genericdeclaration.interfaceCommonBodyDeclaration();
GenericDeclarationList gtv = TypeGenerator.convert(genericdeclaration.genericDeclarationList(), name, commonbody.identifier().getText(), reg, generics);
methods.add(convert(genericmethodmodifiers, commonbody, gtv, generics));
break;
default:
throw new NotImplementedException();
}
}
}
List<RefType> extendedInterfaces = new ArrayList<>();
if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
}
List<RefType> permittedSubtypes = new ArrayList<>();
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");
}
}
var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, methods.size() == 1 ? true : false, extendedInterfaces, permittedSubtypes, ctx.getStart(), fileName);
}
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
CommonToken gtvOffset = new CommonToken(classNameIdentifier);
gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine() + classNameIdentifier.getText().length());
gtvOffset.setStartIndex(gtvOffset.getStopIndex() + 1);
return new GenericDeclarationList(new ArrayList<>(), gtvOffset);
}
private Field convert(InterfaceconstContext constant) {
// TODO: Erstelle hier ein Feld!
throw new NotImplementedException();
}
private Method convert(int modifiers, InterfaceCommonBodyDeclarationContext bodydeclaration, GenericDeclarationList gtvDeclarations, GenericsRegistry generics) {
String name = bodydeclaration.identifier().getText();
RefTypeOrTPHOrWildcardOrGeneric retType;
if (Objects.isNull(bodydeclaration.refType())) {
retType = TypePlaceholder.fresh(bodydeclaration.getStart());
} else {
if (bodydeclaration.refType() instanceof RefType2Context reftype) {
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
} else {
retType = new Void(bodydeclaration.refType().getStart());
}
}
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
MethodBodyContext body = bodydeclaration.methodBody();
Block block = null;
if (!(body instanceof EmptymethodContext)) {
MethodblockContext methodblock = (MethodblockContext) body;
block = stmtgen.convert(methodblock.block(), true);
}
else {
modifiers += Modifier.ABSTRACT;
}
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, bodydeclaration.getStart());
}
protected static Block prepareBlock(Block constructorBlock, RefType superClass) {
List<Statement> statements = constructorBlock.getStatements();
if (statements.isEmpty() || !(statements.get(0) instanceof SuperCall)) {
var signature = new ArrayList<RefTypeOrTPHOrWildcardOrGeneric>();
signature.add(new Void(new NullToken()));
statements.add(0, new SuperCall(superClass, signature, constructorBlock.getOffset()));
}
/* statements.addAll(fieldInitializations); geloescht PL 2018-11-24 */
return new Block(statements, constructorBlock.getOffset());
}
/**
* http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9
*/
private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, params, prepareBlock(new Block(new ArrayList<>(), offset), superClass), classGenerics, offset); // fieldInitializations // 2018-11-24
}
/*
* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert
*/
private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, params, new Block(new ArrayList<>(initializations), offset), classGenerics, offset);
}
private Method generateStaticConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(initializations), offset);
return new Method(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset);
}
private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) {
ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType();
if (supertypecontext != null && supertypecontext.DOT().size() > 0) {
throw new NotImplementedException();
} else {
TypeArgumentsContext typeArguments = (typeType.classOrInterfaceType().typeArguments().size() > 0) ? typeType.classOrInterfaceType().typeArguments().get(typeType.classOrInterfaceType().typeArguments().size() - 1) : null;
RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(typeType.classOrInterfaceType().typeIdentifier().getText(), typeArguments, typeType.getStart(), reg, globalGenerics);
if (ret instanceof RefType) {
return (RefType) ret;
} else {
throw new TypeinferenceException(typeType.getText() + " ist kein gültiger Supertyp", typeType.getStart());
}
}
}
private List<RefType> convert(Java17Parser.TypeListContext ctx, GenericsRegistry generics) {
List<RefType> ret = new ArrayList<>();
for (Java17Parser.TypeTypeContext type : ctx.typeType()) {
ret.add((RefType) TypeGenerator.convert(type, reg, generics));
}
return ret;
}
public Method convert(int modifiers, Java17Parser.MethodContext methodContext, JavaClassName parentClass, RefType superClass, GenericsRegistry generics) {
GenericsRegistry localgenerics = generics;
MethodDeclarationContext methoddeclaration;
GenericDeclarationListContext genericdeclarations;
GenericDeclarationList gtvDeclarations;
MethodHeaderContext header;
String name;
if (methodContext instanceof GenericmethodContext) {
GenericmethodContext gmc = (GenericmethodContext) methodContext;
genericdeclarations = gmc.genericMethodDeclaration().genericDeclarationList();
methoddeclaration = gmc.genericMethodDeclaration().methodDeclaration();
header = methoddeclaration.methodHeader();
name = header.identifier().getText();
localgenerics.putAll(createGenerics(genericdeclarations, parentClass, name, reg, generics));
gtvDeclarations = TypeGenerator.convert(genericdeclarations, parentClass, name, reg, localgenerics);
} else {
MethoddeclContext mdc = (MethoddeclContext) methodContext;
methoddeclaration = mdc.methodDeclaration();
header = methoddeclaration.methodHeader();
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart());
name = header.identifier().getText();
}
RefTypeOrTPHOrWildcardOrGeneric retType;
if (Objects.isNull(header.refType())) {
retType = TypePlaceholder.fresh(header.getStart());
} else {
if (header.refType() instanceof RefType2Context reftype) {
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
} else {
retType = new Void(header.refType().getStart());
}
}
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
MethodBodyContext body = methoddeclaration.methodBody();
Block block = null;
if (body instanceof EmptymethodContext emptymethod) {
if (!Modifier.isAbstract(modifiers)) {
// TODO: Error! Abstrakte Methode ohne abstrakt Keyword
}
} else {
MethodblockContext methodblock = (MethodblockContext) body;
block = stmtgen.convert(methodblock.block(), true);
}
if (name.equals(parentClass.getClassName())) {
return new Constructor(modifiers, name, retType, paramlist, prepareBlock(block, superClass), gtvDeclarations, methoddeclaration.getStart());
} else {
return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, methoddeclaration.getStart());
}
}
public Constructor convert(int modifiers, Java17Parser.ConstructorContext constructorContext, JavaClassName parentClass, RefType superClass, GenericsRegistry generics) {
GenericsRegistry localgenerics = generics;
GenericDeclarationListContext genericdeclarations;
GenericDeclarationList gtvDeclarations;
ConstructorDeclarationContext constructordeclaration;
String name;
if (constructorContext instanceof GenericconstructorContext) {
GenericconstructorContext genericconstructor = (GenericconstructorContext) constructorContext;
GenericConstructorDeclarationContext gcdeclaration = genericconstructor.genericConstructorDeclaration();
name = gcdeclaration.constructorDeclaration().identifier().getText();
genericdeclarations = gcdeclaration.genericDeclarationList();
constructordeclaration = gcdeclaration.constructorDeclaration();
localgenerics.putAll(createGenerics(genericdeclarations, parentClass, name, reg, generics));
gtvDeclarations = TypeGenerator.convert(genericdeclarations, parentClass, name, reg, localgenerics);
} else {
ConstructordeclContext constructordeclarationcontext = (ConstructordeclContext) constructorContext;
constructordeclaration = constructordeclarationcontext.constructorDeclaration();
name = constructordeclaration.identifier().getText();
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), constructordeclaration.getStart());
}
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
}
List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) {
List<Field> ret = new ArrayList<>();
RefTypeOrTPHOrWildcardOrGeneric fieldType;
if (fieldDeclContext.typeType() != null) {
fieldType = TypeGenerator.convert(fieldDeclContext.typeType(), reg, generics);
} else {
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
// Modifier zu bekommen
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
}
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
String fieldName = varDecl.variableDeclaratorId().getText();
this.fields.put(fieldName, new FieldEntry(fieldName, fieldType, modifiers));
if (varDecl.variableInitializer() != null) {
initializeField(varDecl, Modifier.isStatic(modifiers), fieldType, generics);
}
ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart()));
}
return ret;
}
public static String convert(Java17Parser.VariableDeclaratorIdContext variableDeclaratorIdContext) {
return variableDeclaratorIdContext.getText();
}
// Initialize a field by creating implicit constructor.
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, boolean isStatic, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField);
if (isStatic) {
staticFieldInitializations.add(assignment);
}
else fieldInitializations.add(assignment);
}
public int convertModifier(String modifier) {
return allmodifiers.get(modifier);
}
private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) {
GenericsRegistry ret = new GenericsRegistry(this.globalGenerics);
ret.putAll(generics);
if (ctx == null)
return ret;
for (Java17Parser.GenericTypeVarContext tp : ctx.genericTypeVar()) {
ret.put(tp.identifier().getText(), new GenericContext(parentClass, parentMethod));
TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret);
}
return ret;
}
}

@ -0,0 +1,209 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.IdentifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypeArgumentsContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.TypeTypeContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.WildcardTypeContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TypeGenerator {
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java17Parser.ClassOrInterfaceTypeContext classOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
Java17Parser.TypeArgumentsContext arguments = null;
/*
* PL 2019-03-19 auskommentiert ANFANG if(unannClassOrInterfaceTypeContext. unannClassType_lfno_unannClassOrInterfaceType() != null){ arguments = unannClassOrInterfaceTypeContext. unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); }else{// if(unannClassOrInterfaceTypeContext. unannInterfaceType_lfno_unannClassOrInterfaceType() != null){ arguments = unannClassOrInterfaceTypeContext. unannInterfaceType_lfno_unannClassOrInterfaceType().
* unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); } PL 2019-03-19 auskommentiert ENDE
*/
/**
* Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten Beispiel: Typ<String>.InnererTyp<Integer>
*/
if (classOrInterfaceTypeContext.typeArguments().size() > 1)
throw new NotImplementedException();
String name = "";
for (IdentifierContext id : classOrInterfaceTypeContext.identifier()) {
name += id.getText() + '.';
}
name += classOrInterfaceTypeContext.typeIdentifier().getText();
if (classOrInterfaceTypeContext.getStop().getText().equals(">")) {
/*
* Fuer Debug-Zwecke unannClassOrInterfaceTypeContext. unannInterfaceType_lfno_unannClassOrInterfaceType(); unannClassOrInterfaceTypeContext. unannClassType_lfno_unannClassOrInterfaceType().getText(); //unannClassOrInterfaceTypeContext. unannInterfaceType_lfno_unannClassOrInterfaceType(). unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); //UnannClassType_lfno_unannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType( 0);
* unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType( 0).getText(); unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType( 1); unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType( 1).getText(); unannClassOrInterfaceTypeContext. unannClassType_lfno_unannClassOrInterfaceType().getText(); //unannClassOrInterfaceTypeContext. unannInterfaceType_lf_unannClassOrInterfaceType(); //unannClassOrInterfaceTypeContext.
* unannInterfaceType_lf_unannClassOrInterfaceType(0).getText(); //unannClassOrInterfaceTypeContext. unannInterfaceType_lf_unannClassOrInterfaceType(1).getText(); //unannClassOrInterfaceTypeContext. unannInterfaceType_lfno_unannClassOrInterfaceType().getText();
*/
List<TypeArgumentsContext> typeargs = classOrInterfaceTypeContext.typeArguments();
arguments = typeargs.size() != 0 ? classOrInterfaceTypeContext.typeArguments(0) : null;
}
return convertTypeName(name, arguments, classOrInterfaceTypeContext.getStart(), reg, generics);
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java17Parser.TypeTypeContext typeContext, JavaClassRegistry reg, GenericsRegistry genericsRegistry) {
if (typeContext.primitiveType() != null) {
switch (typeContext.primitiveType().getText()) {
case "boolean":
return new RefType(ASTFactory.createClass(Boolean.class).getClassName(), typeContext.getStart());
case "int":
return new RefType(ASTFactory.createClass(Integer.class).getClassName(), typeContext.getStart());
case "double":
return new RefType(ASTFactory.createClass(Double.class).getClassName(), typeContext.getStart());
default:
throw new NotImplementedException();
}
} else if (!typeContext.LBRACK().isEmpty()) { // ArrayType über eckige Klammer prüfen
// System.out.println(unannTypeContext.getText());
throw new NotImplementedException();
}
/*
* else if (typeContext.classOrInterfaceType() != null) { JavaClassName name = reg .getName(typeContext.classOrInterfaceType().typeIdentifier().getText()); return new RefType(name, typeContext.getStart()); }
*/
return TypeGenerator.convert(typeContext.classOrInterfaceType(), reg, genericsRegistry);
}
public static GenericDeclarationList convert(Java17Parser.GenericDeclarationListContext typeParametersContext, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) {
Token endOffset = typeParametersContext.getStop();
List<GenericTypeVar> typeVars = new ArrayList<>();
for (Java17Parser.GenericTypeVarContext typeParameter : typeParametersContext.genericTypeVar()) {
typeVars.add(convert(typeParameter, parentClass, parentMethod, reg, generics));
endOffset = typeParameter.getStop();
}
return new GenericDeclarationList(typeVars, endOffset);
}
public static GenericTypeVar convert(Java17Parser.GenericTypeVarContext typeVar, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) {
String name = typeVar.identifier().getText();
// TODO: Es müssen erst alle GenericTypeVars generiert werden, dann können die
// bounds dieser Generics ermittelt werden
// Problem <A extends B, B> ist erlaubt, würde aber bei den Bounds von A den
// Generic B nicht als solchen erkennen
List<RefTypeOrTPHOrWildcardOrGeneric> bounds = TypeGenerator.convert(typeVar.typeBound(), reg, generics);
GenericTypeVar ret = new GenericTypeVar(name, bounds, typeVar.getStart(), typeVar.getStop());
return ret;
}
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java17Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if (Objects.isNull(typeBoundContext)) {
ret.add(ASTFactory.createObjectType());
return ret;
}
if (typeBoundContext.typeType().size() > 0) {
for (TypeTypeContext tt : typeBoundContext.typeType()) {
ret.add(convert(tt, reg, generics));
}
return ret;
}
throw new NotImplementedException();
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java17Parser.WildcardTypeContext wildcardContext, JavaClassRegistry reg, GenericsRegistry generics) {
if (wildcardContext.getChildCount() < 3) {
if (!Objects.isNull(wildcardContext.extendsWildcardType())) {
return new ExtendsWildcardType(convert(wildcardContext.extendsWildcardType().typeType(), reg, generics), wildcardContext.getStart());
} else if (!Objects.isNull(wildcardContext.superWildcardType())) {
return new SuperWildcardType(convert(wildcardContext.superWildcardType().typeType(), reg, generics), wildcardContext.getStart());
} else {
return new ExtendsWildcardType(new RefType(new JavaClassName("java.lang.Object"), new NullToken()), wildcardContext.getStart());
}
} else {
throw new NotImplementedException(); // Wildcard ohne Bound
}
}
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics) {
return convertTypeName(name, (Java17Parser.TypeArgumentsContext) null, offset, reg, generics);
}
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Java17Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics) {
if (!reg.contains(name)) { // Dann könnte es ein generischer Type oder ein FunN$$-Type sein
if (generics.contains(name)) {
return new GenericRefType(name, offset);
} else {
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(name);
if (m.matches()) {// es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
} else {
throw new TypeinferenceException("Der Typ " + name + " ist nicht vorhanden", offset);
}
}
}
if (typeArguments == null) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (int i = 0; i < reg.getNumberOfGenerics(name); i++) {
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(reg.getName(name), params, offset);
} else {
return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset);
}
}
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Java17Parser.NonWildcardTypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics) {
if (!reg.contains(name)) { // Dann könnte es ein generischer Type oder ein FunN$$-Type sein
if (generics.contains(name)) {
return new GenericRefType(name, offset);
} else {
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(name);
if (m.matches()) {// es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
} else {
throw new TypeinferenceException("Der Typ " + name + " ist nicht vorhanden", offset);
}
}
}
if (typeArguments == null) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (int i = 0; i < reg.getNumberOfGenerics(name); i++) {
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(reg.getName(name), params, offset);
} else {
return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset);
}
}
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java17Parser.TypeArgumentsContext typeArguments, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
for (Java17Parser.TypeArgumentContext arg : typeArguments.typeArgument()) {
WildcardTypeContext wc = arg.wildcardType();
if (!Objects.isNull(wc)) {
ret.add(convert(wc, reg, generics));
} else {
ret.add(convert(arg.typeType(), reg, generics));
}
}
return ret;
}
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java17Parser.NonWildcardTypeArgumentsContext typeArguments, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
for (Java17Parser.TypeTypeContext arg : typeArguments.typeList().typeType()) {
ret.add(convert(arg, reg, generics));
}
return ret;
}
}

@ -0,0 +1,5 @@
= Grammatik =
* Core-Problem: Typinferenz vs. Konstruktoren
* möglicherweise Problem: falsche Return-Expressions

File diff suppressed because one or more lines are too long

@ -0,0 +1,874 @@
// Generated from java-escape by ANTLR 4.11.1
package de.dhbwstuttgart.parser.antlr;
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"})
public class Java17Lexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.11.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);
}
}
}

File diff suppressed because one or more lines are too long

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

@ -0,0 +1,15 @@
* Methode als statische Klasse
* Methode gibt eine JavaClassRegistry zurück (für mehr als 1 S0ourcefile).
* Suchmuster: \n rule
* Generell: lieber leere Listen und wenig null verwenden (Spezialfälle ausgenommen).
== Fehler/Exceptions ==
* Eigene wie z.B. TypeCheckExceptions
* Fehler sollen an Semantikchecker usw. weiter gegeben werden.
== Offset ==
* Evtl. Zeichen im File/in der Klasse durch Antlr ermitteln.
* z.B. ParserRuleContext.getStart()
* Anstatt offset: Instanz des entsprechenden ParserRuleContext (liefert evtl. noch mehr Infos)

@ -0,0 +1,3 @@
* fieldDeclarations
* Imports
* (Q)Generics

@ -0,0 +1,2 @@
* Ablegen der Type Parameter: kompletter Name?
* Typen (unannType etc.)

@ -0,0 +1,18 @@
* Listener-Pattern für das Projekt eher ungeeignet.
= Herangehensweise/Format =
* CompilatunUnit (Rot) wird zu Source-File (Root)
* Im Paket Syntaxtree finden sich die Klassen, die ich letztendlich erzeugen muss.
* Kann hier auch Veränderungen vornehmen (Pull Request)
* Wichtig! Typnamen müssen aufgelöst werden können (also z.B. java.lang.util.ArrayList (JavaClassRegistry).
= Idee bei mehreren Files =
* Zunächst alle Files anschauen und Pakate/Klassen für die spätere Verwendung "registrieren".
* Danach erst das komplette Package/alle Klassen imselben Verzeichnis parsen.
== Fragen/PProbleme SyntaxTreeGenerator ==
* ClassRegistry: Unklar, woher diese kommen soll.
* Konstruktor für Class fehlt.
* Namenskonflikt Class vs. Class in Java?

@ -0,0 +1,166 @@
package de.dhbwstuttgart.parser.scope;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.google.common.collect.Iterables;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.environment.PackageCrawler;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.antlr.Java17Parser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.AnnotationTypeElementDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantsContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SubclassorinterfaceContext;
public class GatherNames {
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
if (clsoifctx instanceof NoclassorinterfaceContext) {
continue;
}
ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, compiler));
}
ret.putAll(getImports(ctx, packages, compiler));
return ret;
}
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx;
String nameString = "";
String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName();
String classname = fullname.substring(fullname.indexOf("$") + 1);
int numGenerics = 0;
/*
* Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden.
*/
switch (classname) {
case "ClassDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
} else {
nameString = clsoif.classDeclaration().identifier().getText();
}
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, compiler));
break;
case "EnumDeclarationContext":
if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText();
} else {
nameString = clsoif.enumDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
EnumConstantsContext enumConstants = clsoif.enumDeclaration().enumConstants();
if (!Objects.isNull(enumConstants)) {
for (EnumConstantContext enumConstant : enumConstants.enumConstant()) {
ClassBodyContext enumConstClassBody = enumConstant.classBody();
if (!Objects.isNull(enumConstClassBody)) {
ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, compiler));
}
}
}
break;
case "InterfaceDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText();
} else {
nameString = clsoif.interfaceDeclaration().identifier().getText();
}
numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) {
if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) {
ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, compiler));
}
}
break;
case "AnnotationTypeDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText();
} else {
nameString = clsoif.annotationTypeDeclaration().identifier().getText();
}
numGenerics = 0;
ret.put(nameString, numGenerics);
for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) {
ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface();
if (!Objects.isNull(anClsoifctx)) {
ret.putAll(getNames(anClsoifctx, pkgName, packages, compiler));
}
}
break;
case "RecordDeclarationContext":
if (pkgName != "") {
nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText();
} else {
nameString = clsoif.recordDeclaration().identifier().getText();
}
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
ret.put(nameString, numGenerics);
ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, compiler));
break;
default:
throw new NotImplementedException();
}
return ret;
}
public static Map<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
for (ClassBodyDeclarationContext clsbody : clsBodyDecl) {
if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) {
ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, compiler));
}
}
return ret;
}
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>();
// ret.putAll(packages.getClassNames("java.lang"));
for (Java17Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()) {
if (importDeclCtx.MUL() == null) {
var name = importDeclCtx.qualifiedName().getText();
var className = new JavaClassName(name);
if (compiler.loadJavaTXClass(className)) {
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
} else {
Class<?> cl = compiler.getClassLoader().loadClass(name);
ret.put(cl.getName(), cl.getTypeParameters().length);
}
} else if (importDeclCtx.MUL() != null) {
// TODO Find stuff in user defined packages
ret.putAll(packages.getClassNames(importDeclCtx.qualifiedName().getText()));
}
// Die Unterscheidungen für 'static imports' wurden herausgenommen, da sie den
// auszuführenden Code nicht beeinflussen
}
return ret;
}
private static String getPackageName(Java17Parser.SrcfileContext ctx) {
String pkgName = "";
if (ctx.packageDeclaration() != null) {
pkgName = ctx.packageDeclaration().qualifiedName().getText();
}
return pkgName;
}
}

@ -0,0 +1,50 @@
package de.dhbwstuttgart.parser.scope;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class GenericsRegistry {
private final List<GenericVariable> registry = new ArrayList<>();
public final GenericsRegistry globalRegistry;
public GenericsRegistry(GenericsRegistry globalRegistry){
this.globalRegistry = globalRegistry;
}
public void put(String name, GenericContext genericContext){
registry.add(new GenericVariable(genericContext,name));
if(globalRegistry != null)globalRegistry.put(name, genericContext);
}
public boolean contains(String name) {
Optional<Boolean> ret = registry.stream().<Boolean>map(((GenericVariable genericVariable) -> genericVariable.name.equals(name)))
.reduce(((a, b) -> a || b));
if(ret.isPresent())
return ret.get();
return false;
}
public GenericContext get(String name) {
return registry.stream()
.filter((genericVariable -> genericVariable.name.equals(name))).findAny().get().context;
}
public void putAll(GenericsRegistry generics) {
for(GenericVariable generic : generics.registry){
this.put(generic.name, generic.context);
}
}
}
class GenericVariable{
final GenericContext context;
final String name;
GenericVariable(GenericContext context, String name){
this.context = context;
this.name = name;
}
}

@ -0,0 +1,159 @@
package de.dhbwstuttgart.parser.scope;
import java.util.ArrayList;
import java.util.List;
/**
* Stellt den Namen einer Java Klasse dar.
* Dieser kann auch den Packagenamen mit beinhalten:
* de.dhbwstuttgart.typeinference.Menge
*
* @author Andreas Stadelmeier
*/
public class JavaClassName {
// FIXME It's very much possible to have imports to inner classes
// In that case a.package.Foo.Bar, a.package is the Package and Foo.Bar the class name
// Its impossible to decide what's the package based solely on the name of the class
public static final JavaClassName Void = new JavaClassName("void");
private String name;
private PackageName packageName;
public JavaClassName(String name) {
if (name == null)
throw new NullPointerException();
String[] names = name.split("[.]");
boolean match = true;
if (names.length == 1) {
// packageName = new PackageName();
this.name = name;
} else {
name = names[names.length - 1];
List<String> packageNames = new ArrayList<String>();
for (int i = 0; i < names.length - 1; i++) {
packageNames.add(names[i]);
}
packageName = new PackageName(packageNames);
this.name = names[names.length - 1];
}
}
/**
* Gibt von einem Klassennamen nur den Namen der Klasse zur<75>ck
* Beispiel:
* java.lang.Object wird zu: Object
*/
public static String stripClassName(String className) {
return new JavaClassName(className).name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
/*
* result = prime * result
* + ((packageName == null) ? 0 : packageName.hashCode()); //PackageName does
* not infect hashCode
*/
return result;
}
/**
* Namen sind nur gleich, wenn bei den beiden zu vergleichenden JavaClassNames
* auch das Package angegeben ist
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (obj instanceof String)
return this.toString().equals(obj) || (this.name != null && this.name.equals(obj)); // Auch mit Strings als
// Klassennamen kompatibel
// TODO: sollte bald obsolet
// sein
if (getClass() != obj.getClass())
return false;
JavaClassName other = (JavaClassName) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (packageName != null && other.packageName != null) {
if (!packageName.equals(other.packageName))
return false;// Spezialfall, nicht beide Typen müssen eindeutig mit Packagenamen angegeben
// werden
}
return true;
}
@Override
public String toString() {
return (packageName != null ? packageName.toString() + "." : "") + name;
}
public String getPackageName() {
return (packageName != null ? packageName.toString() : "");
}
public String getClassName() {
return name;
}
}
class PackageName {
List<String> names = new ArrayList<>();
public PackageName(List<String> packageNames) {
names = packageNames;
}
public PackageName() {
// Do nothing
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((names == null) ? 0 : names.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PackageName other = (PackageName) obj;
if (names == null) {
if (other.names != null)
return false;
} else if (!names.equals(other.names))
return false;
return true;
}
@Override
public String toString() {
String ret = "";
if (names == null)
return "";
for (String n : names)
ret += n + ".";
if (ret != null && ret.length() > 0 && ret.charAt(ret.length() - 1) == '.') {
ret = ret.substring(0, ret.length() - 1);
}
return ret;
}
}

@ -0,0 +1,65 @@
package de.dhbwstuttgart.parser.scope;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import java.util.*;
/**
* Speichert die Klassen f<>r einen bestimmten Projektscope
*/
public class JavaClassRegistry {
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
public JavaClassRegistry(Map<String, Integer> initialNames) {
addNames(initialNames);
}
public JavaClassRegistry() {}
public void addNames(Map<String, Integer> names) {
for (String name : names.keySet()) {
existingClasses.put(new JavaClassName(name), names.get(name));
}
}
public void addName(String className, int numberOfGenerics) {
existingClasses.put(new JavaClassName(className), numberOfGenerics);
}
public JavaClassName getName(String className) {
for (JavaClassName name : existingClasses.keySet()) {
if (name.equals(new JavaClassName(className)))
return name;
}
throw new RuntimeException("Class " + className + " not found!");
}
@Override
public String toString() {
return existingClasses.toString();
}
public List<JavaClassName> getAllFromPackage(String packageName) {
List<JavaClassName> ret = new ArrayList<>();
for (JavaClassName className : this.existingClasses.keySet()) {
JavaClassName toCompare = new JavaClassName(
packageName + "." + JavaClassName.stripClassName(className.toString()));
if (toCompare.toString().equals(className.toString())) {
ret.add(className);
}
}
return ret;
}
public boolean contains(String whole) {
return existingClasses.containsKey(new JavaClassName(whole));
}
public boolean contains(JavaClassName name) {
return existingClasses.containsKey(name);
}
public int getNumberOfGenerics(String name) {
return existingClasses.get(new JavaClassName(name));
}
}

@ -0,0 +1,41 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.*;
public interface ASTVisitor extends StatementVisitor{
void visit(SourceFile sourceFile);
void visit(GenericTypeVar genericTypeVar);
void visit(FormalParameter formalParameter);
void visit(GenericDeclarationList genericTypeVars);
void visit(Field field);
void visit(Method field);
void visit(Constructor field);
void visit(ParameterList formalParameters);
void visit(ClassOrInterface classOrInterface);
void visit(RefType refType);
void visit(SuperWildcardType superWildcardType);
void visit(TypePlaceholder typePlaceholder);
void visit(ExtendsWildcardType extendsWildcardType);
void visit(GenericRefType genericRefType);
void visit(ExpressionPattern aPattern);
void visit(RecordPattern aRecordPattern);
void visit(GuardedPattern aGuardedPattern);
}

@ -0,0 +1,333 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.Iterator;
import java.util.Objects;
import de.dhbwstuttgart.syntaxtree.*;
public abstract class AbstractASTWalker implements ASTVisitor {
@Override
public void visit(Constructor cons) {
visitMethod(cons);
}
@Override
public void visit(SourceFile sourceFile) {
for (ClassOrInterface cl : sourceFile.getClasses()) {
cl.accept(this);
}
}
@Override
public void visit(ArgumentList argumentList) {
for (Expression expr : argumentList.getArguments()) {
expr.accept(this);
}
}
@Override
public void visit(GenericTypeVar genericTypeVar) {
}
@Override
public void visit(FormalParameter formalParameter) {
formalParameter.getType().accept((ASTVisitor) this);
}
@Override
public void visit(GenericDeclarationList genericTypeVars) {
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
if (genericIterator.hasNext()) {
while (genericIterator.hasNext()) {
genericIterator.next().accept(this);
}
}
}
@Override
public void visit(Field field) {
field.getType().accept(this);
}
@Override
public void visit(Method method) {
visitMethod(method);
}
private void visitMethod(Method method) {
method.getReturnType().accept(this);
method.getParameterList().accept(this);
if (method.block != null)
method.block.accept(this);
}
@Override
public void visit(ParameterList formalParameters) {
Iterator<Pattern> it = formalParameters.getFormalparalist().iterator();
if (it.hasNext()) {
while (it.hasNext()) {
it.next().accept(this);
}
}
}
@Override
public void visit(ClassOrInterface classOrInterface) {
classOrInterface.getGenerics().accept(this);
for (Field f : classOrInterface.getFieldDecl()) {
f.accept(this);
}
for (Constructor c : classOrInterface.getConstructors()) {
c.accept(this);
}
for (Method m : classOrInterface.getMethods()) {
m.accept(this);
}
}
@Override
public void visit(RefType refType) {
Iterator<RefTypeOrTPHOrWildcardOrGeneric> genericIterator = refType.getParaList().iterator();
if (genericIterator.hasNext()) {
while (genericIterator.hasNext()) {
genericIterator.next().accept(this);
}
}
}
@Override
public void visit(SuperWildcardType superWildcardType) {
superWildcardType.getInnerType().accept(this);
}
@Override
public void visit(TypePlaceholder typePlaceholder) {
}
@Override
public void visit(ExtendsWildcardType extendsWildcardType) {
extendsWildcardType.getInnerType().accept(this);
}
@Override
public void visit(GenericRefType genericRefType) {
}
@Override
public void visit(LambdaExpression lambdaExpression) {
lambdaExpression.params.accept(this);
lambdaExpression.methodBody.accept(this);
}
@Override
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
assign.rightSide.getType().accept((ASTVisitor) this);
}
@Override
public void visit(BinaryExpr binary) {
}
@Override
public void visit(BoolExpression logical) {
}
@Override
public void visit(Block block) {
for (Statement stmt : block.getStatements()) {
stmt.accept(this);
}
}
@Override
public void visit(CastExpr castExpr) {
}
@Override
public void visit(EmptyStmt emptyStmt) {
}
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
}
@Override
public void visit(ForStmt forStmt) {
forStmt.block.accept(this);
}
@Override
public void visit(ForEachStmt forEachStmt) {
forEachStmt.block.accept(this);
}
@Override
public void visit(IfStmt ifStmt) {
ifStmt.then_block.accept(this);
if (!Objects.isNull(ifStmt.else_block))
ifStmt.else_block.accept(this);
}
@Override
public void visit(InstanceOf instanceOf) {
}
@Override
public void visit(LocalVar localVar) {
}
@Override
public void visit(LocalVarDecl localVarDecl) {
localVarDecl.getType().accept(this);
}
@Override
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
methodCall.getArgumentList().accept(this);
methodCall.getArgumentList().getArguments().forEach(a -> a.getType().accept((ASTVisitor) this));
}
@Override
public void visit(NewClass methodCall) {
visit((MethodCall) methodCall);
}
@Override
public void visit(NewArray newArray) {
}
@Override
public void visit(ExpressionReceiver receiver) {
receiver.expr.accept(this);
}
@Override
public void visit(UnaryExpr unaryExpr) {
unaryExpr.expr.accept(this);
}
@Override
public void visit(Return aReturn) {
aReturn.retexpr.accept(this);
aReturn.getType().accept((ASTVisitor) this);
}
@Override
public void visit(ReturnVoid aReturn) {
}
@Override
public void visit(Break aBreak) {
aBreak.accept(this);
}
@Override
public void visit(StaticClassName staticClassName) {
}
@Override
public void visit(Super aSuper) {
}
@Override
public void visit(This aThis) {
}
@Override
public void visit(WhileStmt whileStmt) {
whileStmt.loopBlock.accept(this);
}
@Override
public void visit(DoStmt whileStmt) {
whileStmt.loopBlock.accept(this);
}
@Override
public void visit(Literal literal) {
}
@Override
public void visit(Throw aThrow) {
}
@Override
public void visit(AssignToField assignLeftSide) {
assignLeftSide.field.accept(this);
}
@Override
public void visit(AssignToLocal assignLeftSide) {
assignLeftSide.localVar.accept(this);
}
@Override
public void visit(SuperCall superCall) {
this.visit((MethodCall) superCall);
}
@Override
public void visit(Switch switchStmt) {
switchStmt.getSwitch().accept(this);
switchStmt.getBlocks().stream().forEach((switchBlock) -> {
switchBlock.accept(this);
});
}
@Override
public void visit(SwitchBlock switchBlock) {
switchBlock.getLabels().stream().forEach((label) -> {
label.accept(this);
});
switchBlock.getStatements().stream().forEach((stmt) -> {
stmt.accept(this);
});
}
@Override
public void visit(SwitchLabel switchLabel) {
}
@Override
public void visit(Yield aYield) {
}
@Override
public void visit(ExpressionPattern aPattern) {
}
@Override
public void visit(RecordPattern aRecordPattern) {
}
@Override
public void visit(GuardedPattern aGuardedPattern) {
}
}

@ -0,0 +1,209 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
//import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import java.lang.Boolean;
import java.lang.String;
import java.lang.Integer;
/**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints()
protected int modifiers;
protected JavaClassName name;
private final String fileName;
private List<Field> fields = new ArrayList<>();
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
private Optional<Method> staticInitializer;
private List<Method> methods = new ArrayList<>();
private GenericDeclarationList genericClassParameters;
private RefType superClass;
protected boolean isInterface;
protected boolean isFunctionalInterface;
private List<RefType> implementedInterfaces;
private List<RefType> permittedSubtypes;
private List<Constructor> constructors;
public ClassOrInterface(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, isFunctionalInterface, implementedInterfaces, permittedSubtypes, offset, fileName) {
super(offset);
if (isInterface) {
modifiers = modifiers | Modifier.INTERFACE | Modifier.ABSTRACT;
}
this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.fieldInitializations = fieldInitializations;
this.staticInitializer = staticInitializer;
this.genericClassParameters = genericClassParameters;
this.superClass = superClass;
this.isInterface = isInterface;
this.isFunctionalInterface= isFunctionalInterface;
this.implementedInterfaces = implementedInterfaces;
this.permittedSubtypes = permittedSubtypes;
this.methods = methods;
this.constructors = constructors;
this.fileName = fileName;
}
/*
* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte alle anderen Datenobjekte werden nur kopiert.
*/
public ClassOrInterface(cl) {
super(cl.getOffset());
this.modifiers = cl.modifiers;
this.name = cl.name;
this.fields = new ArrayList<>(cl.fields);
this.fieldInitializations = cl.fieldInitializations;
this.staticInitializer = cl.staticInitializer;
this.genericClassParameters = cl.genericClassParameters;
this.superClass = cl.superClass;
this.isInterface = cl.isInterface;
this.isFunctionalInterface= cl.isFunctionalInterface;
this.implementedInterfaces = cl.implementedInterfaces;
this.methods = new ArrayList<>(cl.methods);
this.constructors = new ArrayList<>(cl.constructors);
this.fileName = cl.fileName;
}
public getFileName() {
return fileName;
}
public getField(name) {
// TODO This should be a map
return fields.stream().filter(field -> field.getName().equals(name)).findFirst();
}
public getStaticInitializer() {
return staticInitializer;
}
public isInterface() {
return (Modifier.INTERFACE & this.getModifiers()) != 0;
}
public isFunctionalInterface() {
return this.isFunctionalInterface;
}
// Gets if it is added
public areMethodsAdded() {
return methodAdded;
}
// Sets that it is added
public setMethodsAdded() {
methodAdded = true;
}
// Gets class name
public getClassName() {
return this.name;
}
// Get modifiers
public getModifiers() {
return this.modifiers;
}
public getFieldDecl() {
return this.fields;
}
public getfieldInitializations() {
return this.fieldInitializations;
}
public getMethods() {
return this.methods;
}
/*
* public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); }
*/
// TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static generateTypeOfClass(name, genericsOfClass, offset) {
// Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar genericTypeVar : genericsOfClass) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(name, params, offset);
}
/**
*
* @return die aktuelle Klasse als RefType
*/
public generateTypeOfThisClass() {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar genericTypeVar : this.getGenerics()) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
}
return new RefType(name, params, new NullToken());
}
/**
* Die Superklasse im Kontext dieser ClassOrInterface Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public getSuperClass() {
return superClass;
}
public getGenerics() {
return this.genericClassParameters;
}
@Override
public getReturnType() {
return null;
}
public getConstructors() {
return constructors;
}
@Override
public accept(visitor) {
visitor.visit(this);
}
public getSuperInterfaces() {
return implementedInterfaces;
}
public toString() {
return this.name.toString() + this.genericClassParameters.toString();
}
}

@ -0,0 +1,191 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/
public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
private Boolean methodAdded = false; // wird benoetigt bei in JavaTXCompiler.getConstraints()
protected int modifiers;
protected JavaClassName name;
private final String fileName;
private List<Field> fields = new ArrayList<>();
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
private Optional<Method> staticInitializer;
private List<Method> methods = new ArrayList<>();
private GenericDeclarationList genericClassParameters;
private RefType superClass;
protected boolean isInterface;
protected boolean isFunctionalInterface;
private List<RefType> implementedInterfaces;
private List<RefType> permittedSubtypes;
private List<Constructor> constructors;
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
super(offset);
if (isInterface) {
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
}
this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.fieldInitializations = fieldInitializations;
this.staticInitializer = staticInitializer;
this.genericClassParameters = genericClassParameters;
this.superClass = superClass;
this.isInterface = isInterface;
this.isFunctionalInterface= isFunctionalInterface;
this.implementedInterfaces = implementedInterfaces;
this.permittedSubtypes = permittedSubtypes;
this.methods = methods;
this.constructors = constructors;
this.fileName = fileName;
}
/*
* erzeugt fuer Fields, Konstruktoren und Methoden neue ArrayList-Objekte alle anderen Datenobjekte werden nur kopiert.
*/
public ClassOrInterface(ClassOrInterface cl) {
super(cl.getOffset());
this.modifiers = cl.modifiers;
this.name = cl.name;
this.fields = new ArrayList<>(cl.fields);
this.fieldInitializations = cl.fieldInitializations;
this.staticInitializer = cl.staticInitializer;
this.genericClassParameters = cl.genericClassParameters;
this.superClass = cl.superClass;
this.isInterface = cl.isInterface;
this.isFunctionalInterface= cl.isFunctionalInterface;
this.implementedInterfaces = cl.implementedInterfaces;
this.methods = new ArrayList<>(cl.methods);
this.constructors = new ArrayList<>(cl.constructors);
this.fileName = cl.fileName;
}
public String getFileName() {
return fileName;
}
public Optional<Field> getField(String name) {
// TODO This should be a map
return fields.stream().filter(field -> field.getName().equals(name)).findFirst();
}
public Optional<Method> getStaticInitializer() {
return staticInitializer;
}
public boolean isInterface() {
return (Modifier.INTERFACE & this.getModifiers()) != 0;
}
public boolean isFunctionalInterface() {
return this.isFunctionalInterface;
}
// Gets if it is added
public Boolean areMethodsAdded() {
return methodAdded;
}
// Sets that it is added
public void setMethodsAdded() {
methodAdded = true;
}
// Gets class name
public JavaClassName getClassName() {
return this.name;
}
// Get modifiers
public int getModifiers() {
return this.modifiers;
}
public List<Field> getFieldDecl() {
return this.fields;
}
public Optional<Constructor> getfieldInitializations() {
return this.fieldInitializations;
}
public List<Method> getMethods() {
return this.methods;
}
/*
* public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); }
*/
// TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass, Token offset) {
// Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar genericTypeVar : genericsOfClass) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(name, params, offset);
}
/**
*
* @return die aktuelle Klasse als RefType
*/
public RefType generateTypeOfThisClass() {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (GenericTypeVar genericTypeVar : this.getGenerics()) {
// params.add(genericTypeVar.getTypePlaceholder());
params.add(new GenericRefType(genericTypeVar.getName(), new NullToken()));
}
return new RefType(name, params, new NullToken());
}
/**
* Die Superklasse im Kontext dieser ClassOrInterface Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() {
return superClass;
}
public GenericDeclarationList getGenerics() {
return this.genericClassParameters;
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return null;
}
public List<Constructor> getConstructors() {
return constructors;
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
public Collection<RefType> getSuperInterfaces() {
return implementedInterfaces;
}
public String toString() {
return this.name.toString() + this.genericClassParameters.toString();
}
}

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