Compare commits
181 Commits
aspGen
...
37c58be1f3
Author | SHA1 | Date | |
---|---|---|---|
|
37c58be1f3 | ||
|
24920330c6 | ||
|
bc43ea749d | ||
9160c99cf2 | |||
c72a14cab3 | |||
10bb5d1d11 | |||
2842fc5069 | |||
5c5e0bd1e9 | |||
3d81318e01 | |||
53e2c20608 | |||
86e467fd82 | |||
25b14e9342 | |||
d0de0b31e4 | |||
dd180524b2 | |||
b3744bf5f7 | |||
fda16978c2 | |||
a485cd8fa6 | |||
f8c708f0f4 | |||
28d9946bbb | |||
7b4ca8f177 | |||
b879d7743d | |||
e26a43b400 | |||
5deed725ae | |||
8ae15f9d41 | |||
8c8e088612 | |||
2814c6538e | |||
dcbc29b49b | |||
05033bcb9d | |||
814f5dd5fa | |||
24ca985ccc | |||
d6ed0689bc | |||
d7676f36e3 | |||
|
c479b044b3 | ||
|
9046fb09e5 | ||
|
9e323759d6 | ||
558083166d | |||
|
aec2f9a399 | ||
|
31df7a65f0 | ||
|
185989ba62 | ||
|
0eb48ba425 | ||
ceee9a49c4 | |||
ee64218a5f | |||
c50f14a4a3 | |||
1f4250ff84 | |||
ae41c7f19d | |||
2416c80c20 | |||
4cc55c0059 | |||
9434facfa0 | |||
09a6b9a788 | |||
8b342c5604 | |||
cdb93b5155 | |||
b07e848fa2 | |||
313cd20f36 | |||
567fcc3b9a | |||
d9936e7197 | |||
8f194b3102 | |||
1391206dfe | |||
659bf6b500 | |||
|
42e31a3471 | ||
|
d3b3f92193 | ||
|
8208abcaea | ||
|
e4a3939ce9 | ||
|
d903ec0ebb | ||
|
61de81cf92 | ||
|
59888006e0 | ||
|
94034912b4 | ||
|
f303163118 | ||
|
7d99fba044 | ||
|
3740d34954 | ||
|
d8b861ea95 | ||
33ed22c06a | |||
70f7857661 | |||
|
cf45ea68bd | ||
|
be72e4d7fb | ||
45275b6888 | |||
2144dd9341 | |||
69c2bb3dc9 | |||
3a57d5e025 | |||
|
1e37538fde | ||
4cdd5d016c | |||
4318856fa8 | |||
1ace099d72 | |||
b76e1e46f0 | |||
09c483542d | |||
77411973be | |||
d0d9c46a67 | |||
|
24bf3d350f | ||
b9f9994de3 | |||
|
f0287c4611 | ||
|
edf609f916 | ||
|
14e2af7d2a | ||
|
158adf837a | ||
46b378e3a5 | |||
484a70c15c | |||
c461e89336 | |||
f846142ee1 | |||
443b8b0c09 | |||
ff715a22cf | |||
170955b333 | |||
88d81f4af7 | |||
bb11d24101 | |||
e2bf09548f | |||
|
c33e372446 | ||
|
7c546834c0 | ||
|
aa61f90fb1 | ||
|
b4da20e1d4 | ||
|
4d1950d0ba | ||
|
cc204f659a | ||
|
5893338783 | ||
e1e744152a | |||
|
fc22299af5 | ||
7811ecce63 | |||
44754e73ac | |||
|
6ee308a712 | ||
85d70378ca | |||
89bbbdacd8 | |||
|
fbde5afb1b | ||
6ccf2a3df6 | |||
b7979ac7e7 | |||
|
9ede47c2d6 | ||
|
406f98e55d | ||
|
a9d836ce25 | ||
|
fd8a66dd59 | ||
|
929392b7d4 | ||
|
f57c8aa5a9 | ||
|
daa38183fa | ||
eb454aa5b2 | |||
72035c48f2 | |||
54f258e333 | |||
|
114de0b236 | ||
|
8f094eb025 | ||
|
3ac3af2327 | ||
|
fbc9f1e755 | ||
|
94c359f7a1 | ||
|
3be557a32b | ||
9801f8a5ae | |||
f0b9bea23e | |||
|
96eb504174 | ||
ce4347dd96 | |||
|
4f0162ba64 | ||
|
6e1198ab3d | ||
7785c2d0aa | |||
|
cc8f36d3ec | ||
|
139325e78f | ||
|
b18b0a38cf | ||
a654f55deb | |||
|
be60261795 | ||
|
c7f4a2d4c1 | ||
|
7037bdf9ef | ||
|
d9860497df | ||
|
fdffc11580 | ||
|
c10de35ca2 | ||
|
56b73332c0 | ||
|
bdcd5ea3cf | ||
edafbbc5a0 | |||
ba8810e5df | |||
63493ed0f7 | |||
|
5f944e441c | ||
|
4dba867f9e | ||
|
06caf0ff66 | ||
ec92b5d5e1 | |||
091a6b8f1f | |||
60a1f3b220 | |||
7e6aeaf728 | |||
|
0d572ed9b6 | ||
|
ea217d16d5 | ||
|
7650813bb7 | ||
|
5d03995f10 | ||
|
1bc58573c7 | ||
4880527d4d | |||
50f2a29e1e | |||
99f219de3b | |||
12bb613eb0 | |||
141e1cbc94 | |||
|
5b4ea5a0c5 | ||
b824680508 | |||
295bf079b9 | |||
974582f7e5 | |||
2ded0c9044 | |||
|
c3343959c5 | ||
|
39f04b1a1b |
@@ -1,5 +1,8 @@
|
|||||||
name: Build and Test with Maven
|
name: Build and Test with Maven
|
||||||
on: [push]
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-and-test-with-Maven:
|
Build-and-test-with-Maven:
|
||||||
@@ -15,11 +18,11 @@ jobs:
|
|||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '21'
|
java-version: '24'
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
- name: Compile project
|
- name: Compile project
|
||||||
run: |
|
run: |
|
||||||
mvn compile
|
mvn compile
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
mvn test
|
mvn test
|
||||||
|
45
.gitea/workflows/sonarqube.yml
Normal file
45
.gitea/workflows/sonarqube.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
name: SonarQube Scan
|
||||||
|
jobs:
|
||||||
|
sonarqube:
|
||||||
|
name: SonarQube Trigger
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checking out
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# Disabling shallow clone is recommended for improving relevancy of reporting
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Install maven
|
||||||
|
run: |
|
||||||
|
apt update
|
||||||
|
apt install -y maven
|
||||||
|
- name: Install java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '24'
|
||||||
|
cache: 'maven'
|
||||||
|
- name: Compile project
|
||||||
|
run: |
|
||||||
|
mvn clean dependency:copy-dependencies verify
|
||||||
|
- name: SonarQube Scan
|
||||||
|
uses: SonarSource/sonarqube-scan-action@v5.3.0
|
||||||
|
env:
|
||||||
|
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }}
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
|
||||||
|
with:
|
||||||
|
args: >
|
||||||
|
-Dsonar.projectKey=Java-TX
|
||||||
|
-Dsonar.sources=src/main/java
|
||||||
|
-Dsonar.tests=src/test/java
|
||||||
|
-Dsonar.junit.reportPaths=target/test-reports
|
||||||
|
-Dsonar.java.binaries=target/classes
|
||||||
|
-Dsonar.java.libraries=target/dependency/*.jar
|
||||||
|
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
|
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## Java-TX Compiler
|
||||||
|
|
||||||
|
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||||
|
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||||
|
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
||||||
|
|
||||||
|
Work in Progress Java-TX Compiler repository!
|
408
gen/Java17Lexer.interp
Normal file
408
gen/Java17Lexer.interp
Normal file
File diff suppressed because one or more lines are too long
873
gen/Java17Lexer.java
Normal file
873
gen/Java17Lexer.java
Normal file
@@ -0,0 +1,873 @@
|
|||||||
|
// Generated from C:/Users/ruben/IdeaProjects/JavaCompilerCore/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Lexer.g4 by ANTLR 4.13.1
|
||||||
|
import org.antlr.v4.runtime.Lexer;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
import org.antlr.v4.runtime.TokenStream;
|
||||||
|
import org.antlr.v4.runtime.*;
|
||||||
|
import org.antlr.v4.runtime.atn.*;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
import org.antlr.v4.runtime.misc.*;
|
||||||
|
|
||||||
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
|
||||||
|
public class Java17Lexer extends Lexer {
|
||||||
|
static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
|
||||||
|
|
||||||
|
protected static final DFA[] _decisionToDFA;
|
||||||
|
protected static final PredictionContextCache _sharedContextCache =
|
||||||
|
new PredictionContextCache();
|
||||||
|
public static final int
|
||||||
|
ABSTRACT=1, ASSERT=2, BOOLEAN=3, BREAK=4, BYTE=5, CASE=6, CATCH=7, CHAR=8,
|
||||||
|
CLASS=9, CONST=10, CONTINUE=11, DEFAULT=12, DO=13, DOUBLE=14, ELSE=15,
|
||||||
|
ENUM=16, EXTENDS=17, FINAL=18, FINALLY=19, FLOAT=20, FOR=21, IF=22, GOTO=23,
|
||||||
|
IMPLEMENTS=24, IMPORT=25, INSTANCEOF=26, INT=27, INTERFACE=28, LONG=29,
|
||||||
|
NATIVE=30, NEW=31, PACKAGE=32, PRIVATE=33, PROTECTED=34, PUBLIC=35, RETURN=36,
|
||||||
|
SHORT=37, STATIC=38, STRICTFP=39, SUPER=40, SWITCH=41, SYNCHRONIZED=42,
|
||||||
|
THIS=43, THROW=44, THROWS=45, TRANSIENT=46, TRY=47, VOID=48, VOLATILE=49,
|
||||||
|
WHILE=50, MODULE=51, OPEN=52, REQUIRES=53, EXPORTS=54, OPENS=55, TO=56,
|
||||||
|
USES=57, PROVIDES=58, WITH=59, TRANSITIVE=60, VAR=61, YIELD=62, RECORD=63,
|
||||||
|
SEALED=64, PERMITS=65, NON_SEALED=66, DECIMAL_LITERAL=67, HEX_LITERAL=68,
|
||||||
|
OCT_LITERAL=69, BINARY_LITERAL=70, FLOAT_LITERAL=71, HEX_FLOAT_LITERAL=72,
|
||||||
|
BOOL_LITERAL=73, CHAR_LITERAL=74, STRING_LITERAL=75, TEXT_BLOCK=76, NULL_LITERAL=77,
|
||||||
|
LPAREN=78, RPAREN=79, LBRACE=80, RBRACE=81, LBRACK=82, RBRACK=83, SEMI=84,
|
||||||
|
COMMA=85, DOT=86, ASSIGN=87, GT=88, LT=89, BANG=90, TILDE=91, QUESTION=92,
|
||||||
|
COLON=93, EQUAL=94, LE=95, GE=96, NOTEQUAL=97, AND=98, OR=99, INC=100,
|
||||||
|
DEC=101, ADD=102, SUB=103, MUL=104, DIV=105, BITAND=106, BITOR=107, CARET=108,
|
||||||
|
MOD=109, ADD_ASSIGN=110, SUB_ASSIGN=111, MUL_ASSIGN=112, DIV_ASSIGN=113,
|
||||||
|
AND_ASSIGN=114, OR_ASSIGN=115, XOR_ASSIGN=116, MOD_ASSIGN=117, LSHIFT_ASSIGN=118,
|
||||||
|
RSHIFT_ASSIGN=119, URSHIFT_ASSIGN=120, ARROW=121, COLONCOLON=122, AT=123,
|
||||||
|
ELLIPSIS=124, WS=125, COMMENT=126, LINE_COMMENT=127, IDENTIFIER=128;
|
||||||
|
public static String[] channelNames = {
|
||||||
|
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static String[] modeNames = {
|
||||||
|
"DEFAULT_MODE"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static String[] makeRuleNames() {
|
||||||
|
return new String[] {
|
||||||
|
"ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR",
|
||||||
|
"CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM",
|
||||||
|
"EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO", "IMPLEMENTS",
|
||||||
|
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW",
|
||||||
|
"PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC",
|
||||||
|
"STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS",
|
||||||
|
"TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE", "OPEN", "REQUIRES",
|
||||||
|
"EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH", "TRANSITIVE", "VAR",
|
||||||
|
"YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED", "DECIMAL_LITERAL",
|
||||||
|
"HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL", "HEX_FLOAT_LITERAL",
|
||||||
|
"BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL", "TEXT_BLOCK", "NULL_LITERAL",
|
||||||
|
"LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", "SEMI", "COMMA",
|
||||||
|
"DOT", "ASSIGN", "GT", "LT", "BANG", "TILDE", "QUESTION", "COLON", "EQUAL",
|
||||||
|
"LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", "SUB", "MUL",
|
||||||
|
"DIV", "BITAND", "BITOR", "CARET", "MOD", "ADD_ASSIGN", "SUB_ASSIGN",
|
||||||
|
"MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
|
||||||
|
"MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "ARROW",
|
||||||
|
"COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT", "LINE_COMMENT", "IDENTIFIER",
|
||||||
|
"ExponentPart", "EscapeSequence", "HexDigits", "HexDigit", "Digits",
|
||||||
|
"LetterOrDigit", "Letter"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public static final String[] ruleNames = makeRuleNames();
|
||||||
|
|
||||||
|
private static String[] makeLiteralNames() {
|
||||||
|
return new String[] {
|
||||||
|
null, "'abstract'", "'assert'", "'boolean'", "'break'", "'byte'", "'case'",
|
||||||
|
"'catch'", "'char'", "'class'", "'const'", "'continue'", "'default'",
|
||||||
|
"'do'", "'double'", "'else'", "'enum'", "'extends'", "'final'", "'finally'",
|
||||||
|
"'float'", "'for'", "'if'", "'goto'", "'implements'", "'import'", "'instanceof'",
|
||||||
|
"'int'", "'interface'", "'long'", "'native'", "'new'", "'package'", "'private'",
|
||||||
|
"'protected'", "'public'", "'return'", "'short'", "'static'", "'strictfp'",
|
||||||
|
"'super'", "'switch'", "'synchronized'", "'this'", "'throw'", "'throws'",
|
||||||
|
"'transient'", "'try'", "'void'", "'volatile'", "'while'", "'module'",
|
||||||
|
"'open'", "'requires'", "'exports'", "'opens'", "'to'", "'uses'", "'provides'",
|
||||||
|
"'with'", "'transitive'", "'var'", "'yield'", "'record'", "'sealed'",
|
||||||
|
"'permits'", "'non-sealed'", null, null, null, null, null, null, null,
|
||||||
|
null, null, null, "'null'", "'('", "')'", "'{'", "'}'", "'['", "']'",
|
||||||
|
"';'", "','", "'.'", "'='", "'>'", "'<'", "'!'", "'~'", "'?'", "':'",
|
||||||
|
"'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", "'--'", "'+'",
|
||||||
|
"'-'", "'*'", "'/'", "'&'", "'|'", "'^'", "'%'", "'+='", "'-='", "'*='",
|
||||||
|
"'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", "'>>>='", "'->'",
|
||||||
|
"'::'", "'@'", "'...'"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||||
|
private static String[] makeSymbolicNames() {
|
||||||
|
return new String[] {
|
||||||
|
null, "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH",
|
||||||
|
"CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE",
|
||||||
|
"ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO",
|
||||||
|
"IMPLEMENTS", "IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE",
|
||||||
|
"NEW", "PACKAGE", "PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT",
|
||||||
|
"STATIC", "STRICTFP", "SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW",
|
||||||
|
"THROWS", "TRANSIENT", "TRY", "VOID", "VOLATILE", "WHILE", "MODULE",
|
||||||
|
"OPEN", "REQUIRES", "EXPORTS", "OPENS", "TO", "USES", "PROVIDES", "WITH",
|
||||||
|
"TRANSITIVE", "VAR", "YIELD", "RECORD", "SEALED", "PERMITS", "NON_SEALED",
|
||||||
|
"DECIMAL_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BINARY_LITERAL", "FLOAT_LITERAL",
|
||||||
|
"HEX_FLOAT_LITERAL", "BOOL_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
|
||||||
|
"TEXT_BLOCK", "NULL_LITERAL", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
|
||||||
|
"LBRACK", "RBRACK", "SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "BANG",
|
||||||
|
"TILDE", "QUESTION", "COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND",
|
||||||
|
"OR", "INC", "DEC", "ADD", "SUB", "MUL", "DIV", "BITAND", "BITOR", "CARET",
|
||||||
|
"MOD", "ADD_ASSIGN", "SUB_ASSIGN", "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN",
|
||||||
|
"OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN",
|
||||||
|
"URSHIFT_ASSIGN", "ARROW", "COLONCOLON", "AT", "ELLIPSIS", "WS", "COMMENT",
|
||||||
|
"LINE_COMMENT", "IDENTIFIER"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
|
||||||
|
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #VOCABULARY} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final String[] tokenNames;
|
||||||
|
static {
|
||||||
|
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||||
|
for (int i = 0; i < tokenNames.length; i++) {
|
||||||
|
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||||
|
if (tokenNames[i] == null) {
|
||||||
|
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenNames[i] == null) {
|
||||||
|
tokenNames[i] = "<INVALID>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public String[] getTokenNames() {
|
||||||
|
return tokenNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
|
||||||
|
public Vocabulary getVocabulary() {
|
||||||
|
return VOCABULARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Java17Lexer(CharStream input) {
|
||||||
|
super(input);
|
||||||
|
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGrammarFileName() { return "Java17Lexer.g4"; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getRuleNames() { return ruleNames; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSerializedATN() { return _serializedATN; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getChannelNames() { return channelNames; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getModeNames() { return modeNames; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ATN getATN() { return _ATN; }
|
||||||
|
|
||||||
|
public static final String _serializedATN =
|
||||||
|
"\u0004\u0000\u0080\u0458\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+
|
||||||
|
"\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+
|
||||||
|
"\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+
|
||||||
|
"\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+
|
||||||
|
"\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
|
||||||
|
"\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+
|
||||||
|
"\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+
|
||||||
|
"\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+
|
||||||
|
"\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+
|
||||||
|
"\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+
|
||||||
|
"\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+
|
||||||
|
"\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+
|
||||||
|
"&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+
|
||||||
|
"+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+
|
||||||
|
"0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+
|
||||||
|
"5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+
|
||||||
|
":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+
|
||||||
|
"?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+
|
||||||
|
"D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+
|
||||||
|
"I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+
|
||||||
|
"N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+
|
||||||
|
"S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+
|
||||||
|
"X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+
|
||||||
|
"]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+
|
||||||
|
"b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+
|
||||||
|
"g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+
|
||||||
|
"l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+
|
||||||
|
"q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+
|
||||||
|
"v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+
|
||||||
|
"{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+
|
||||||
|
"\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+
|
||||||
|
"\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+
|
||||||
|
"\u0002\u0086\u0007\u0086\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+
|
||||||
|
"\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+
|
||||||
|
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
|
||||||
|
"\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
|
||||||
|
"\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
|
||||||
|
"\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+
|
||||||
|
"\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
|
||||||
|
"\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+
|
||||||
|
"\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+
|
||||||
|
"\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+
|
||||||
|
"\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+
|
||||||
|
"\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
|
||||||
|
"\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\r\u0001"+
|
||||||
|
"\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001"+
|
||||||
|
"\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+
|
||||||
|
"\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001"+
|
||||||
|
"\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001"+
|
||||||
|
"\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+
|
||||||
|
"\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001"+
|
||||||
|
"\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001"+
|
||||||
|
"\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001"+
|
||||||
|
"\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
|
||||||
|
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001"+
|
||||||
|
"\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001"+
|
||||||
|
"\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
|
||||||
|
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001"+
|
||||||
|
"\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001"+
|
||||||
|
"\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
|
||||||
|
"\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+
|
||||||
|
"\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001"+
|
||||||
|
"\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001"+
|
||||||
|
"\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f\u0001"+
|
||||||
|
"\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001"+
|
||||||
|
"\u001f\u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001!"+
|
||||||
|
"\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001!\u0001"+
|
||||||
|
"\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+
|
||||||
|
"#\u0001#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0001$\u0001"+
|
||||||
|
"$\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001"+
|
||||||
|
"&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001"+
|
||||||
|
"\'\u0001\'\u0001\'\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001(\u0001"+
|
||||||
|
")\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001)\u0001"+
|
||||||
|
")\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001"+
|
||||||
|
"+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001"+
|
||||||
|
",\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001-\u0001"+
|
||||||
|
"-\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u0001/\u0001/\u0001/\u0001"+
|
||||||
|
"0\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00011\u0001"+
|
||||||
|
"1\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00012\u0001"+
|
||||||
|
"2\u00012\u00013\u00013\u00013\u00013\u00013\u00014\u00014\u00014\u0001"+
|
||||||
|
"4\u00014\u00014\u00014\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+
|
||||||
|
"5\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u00016\u00016\u0001"+
|
||||||
|
"7\u00017\u00017\u00018\u00018\u00018\u00018\u00018\u00019\u00019\u0001"+
|
||||||
|
"9\u00019\u00019\u00019\u00019\u00019\u00019\u0001:\u0001:\u0001:\u0001"+
|
||||||
|
":\u0001:\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001;\u0001"+
|
||||||
|
";\u0001;\u0001;\u0001<\u0001<\u0001<\u0001<\u0001=\u0001=\u0001=\u0001"+
|
||||||
|
"=\u0001=\u0001=\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001>\u0001"+
|
||||||
|
"?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001"+
|
||||||
|
"@\u0001@\u0001@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001A\u0001"+
|
||||||
|
"A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001B\u0001B\u0001B\u0003B\u02d5"+
|
||||||
|
"\bB\u0001B\u0004B\u02d8\bB\u000bB\fB\u02d9\u0001B\u0003B\u02dd\bB\u0003"+
|
||||||
|
"B\u02df\bB\u0001B\u0003B\u02e2\bB\u0001C\u0001C\u0001C\u0001C\u0005C\u02e8"+
|
||||||
|
"\bC\nC\fC\u02eb\tC\u0001C\u0003C\u02ee\bC\u0001C\u0003C\u02f1\bC\u0001"+
|
||||||
|
"D\u0001D\u0005D\u02f5\bD\nD\fD\u02f8\tD\u0001D\u0001D\u0005D\u02fc\bD"+
|
||||||
|
"\nD\fD\u02ff\tD\u0001D\u0003D\u0302\bD\u0001D\u0003D\u0305\bD\u0001E\u0001"+
|
||||||
|
"E\u0001E\u0001E\u0005E\u030b\bE\nE\fE\u030e\tE\u0001E\u0003E\u0311\bE"+
|
||||||
|
"\u0001E\u0003E\u0314\bE\u0001F\u0001F\u0001F\u0003F\u0319\bF\u0001F\u0001"+
|
||||||
|
"F\u0003F\u031d\bF\u0001F\u0003F\u0320\bF\u0001F\u0003F\u0323\bF\u0001"+
|
||||||
|
"F\u0001F\u0001F\u0003F\u0328\bF\u0001F\u0003F\u032b\bF\u0003F\u032d\b"+
|
||||||
|
"F\u0001G\u0001G\u0001G\u0001G\u0003G\u0333\bG\u0001G\u0003G\u0336\bG\u0001"+
|
||||||
|
"G\u0001G\u0003G\u033a\bG\u0001G\u0001G\u0003G\u033e\bG\u0001G\u0001G\u0003"+
|
||||||
|
"G\u0342\bG\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001H\u0001"+
|
||||||
|
"H\u0003H\u034d\bH\u0001I\u0001I\u0001I\u0003I\u0352\bI\u0001I\u0001I\u0001"+
|
||||||
|
"J\u0001J\u0001J\u0005J\u0359\bJ\nJ\fJ\u035c\tJ\u0001J\u0001J\u0001K\u0001"+
|
||||||
|
"K\u0001K\u0001K\u0001K\u0005K\u0365\bK\nK\fK\u0368\tK\u0001K\u0001K\u0001"+
|
||||||
|
"K\u0005K\u036d\bK\nK\fK\u0370\tK\u0001K\u0001K\u0001K\u0001K\u0001L\u0001"+
|
||||||
|
"L\u0001L\u0001L\u0001L\u0001M\u0001M\u0001N\u0001N\u0001O\u0001O\u0001"+
|
||||||
|
"P\u0001P\u0001Q\u0001Q\u0001R\u0001R\u0001S\u0001S\u0001T\u0001T\u0001"+
|
||||||
|
"U\u0001U\u0001V\u0001V\u0001W\u0001W\u0001X\u0001X\u0001Y\u0001Y\u0001"+
|
||||||
|
"Z\u0001Z\u0001[\u0001[\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001^\u0001"+
|
||||||
|
"^\u0001^\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001a\u0001a\u0001"+
|
||||||
|
"a\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001d\u0001d\u0001d\u0001"+
|
||||||
|
"e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001i\u0001"+
|
||||||
|
"j\u0001j\u0001k\u0001k\u0001l\u0001l\u0001m\u0001m\u0001m\u0001n\u0001"+
|
||||||
|
"n\u0001n\u0001o\u0001o\u0001o\u0001p\u0001p\u0001p\u0001q\u0001q\u0001"+
|
||||||
|
"q\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001"+
|
||||||
|
"u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001v\u0001w\u0001w\u0001"+
|
||||||
|
"w\u0001w\u0001w\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001"+
|
||||||
|
"z\u0001{\u0001{\u0001{\u0001{\u0001|\u0004|\u03f5\b|\u000b|\f|\u03f6\u0001"+
|
||||||
|
"|\u0001|\u0001}\u0001}\u0001}\u0001}\u0005}\u03ff\b}\n}\f}\u0402\t}\u0001"+
|
||||||
|
"}\u0001}\u0001}\u0001}\u0001}\u0001~\u0001~\u0001~\u0001~\u0005~\u040d"+
|
||||||
|
"\b~\n~\f~\u0410\t~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0005\u007f\u0416"+
|
||||||
|
"\b\u007f\n\u007f\f\u007f\u0419\t\u007f\u0001\u0080\u0001\u0080\u0003\u0080"+
|
||||||
|
"\u041d\b\u0080\u0001\u0080\u0001\u0080\u0001\u0081\u0001\u0081\u0001\u0081"+
|
||||||
|
"\u0001\u0081\u0003\u0081\u0425\b\u0081\u0001\u0081\u0003\u0081\u0428\b"+
|
||||||
|
"\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0004\u0081\u042d\b\u0081\u000b"+
|
||||||
|
"\u0081\f\u0081\u042e\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001"+
|
||||||
|
"\u0081\u0003\u0081\u0436\b\u0081\u0001\u0082\u0001\u0082\u0001\u0082\u0005"+
|
||||||
|
"\u0082\u043b\b\u0082\n\u0082\f\u0082\u043e\t\u0082\u0001\u0082\u0003\u0082"+
|
||||||
|
"\u0441\b\u0082\u0001\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0005\u0084"+
|
||||||
|
"\u0447\b\u0084\n\u0084\f\u0084\u044a\t\u0084\u0001\u0084\u0003\u0084\u044d"+
|
||||||
|
"\b\u0084\u0001\u0085\u0001\u0085\u0003\u0085\u0451\b\u0085\u0001\u0086"+
|
||||||
|
"\u0001\u0086\u0001\u0086\u0001\u0086\u0003\u0086\u0457\b\u0086\u0002\u036e"+
|
||||||
|
"\u0400\u0000\u0087\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005"+
|
||||||
|
"\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017\f\u0019"+
|
||||||
|
"\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013\'\u0014)\u0015"+
|
||||||
|
"+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d;\u001e=\u001f"+
|
||||||
|
"? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e3g4i5k6m7o8q9s:u;w<y={>}?\u007f"+
|
||||||
|
"@\u0081A\u0083B\u0085C\u0087D\u0089E\u008bF\u008dG\u008fH\u0091I\u0093"+
|
||||||
|
"J\u0095K\u0097L\u0099M\u009bN\u009dO\u009fP\u00a1Q\u00a3R\u00a5S\u00a7"+
|
||||||
|
"T\u00a9U\u00abV\u00adW\u00afX\u00b1Y\u00b3Z\u00b5[\u00b7\\\u00b9]\u00bb"+
|
||||||
|
"^\u00bd_\u00bf`\u00c1a\u00c3b\u00c5c\u00c7d\u00c9e\u00cbf\u00cdg\u00cf"+
|
||||||
|
"h\u00d1i\u00d3j\u00d5k\u00d7l\u00d9m\u00dbn\u00ddo\u00dfp\u00e1q\u00e3"+
|
||||||
|
"r\u00e5s\u00e7t\u00e9u\u00ebv\u00edw\u00efx\u00f1y\u00f3z\u00f5{\u00f7"+
|
||||||
|
"|\u00f9}\u00fb~\u00fd\u007f\u00ff\u0080\u0101\u0000\u0103\u0000\u0105"+
|
||||||
|
"\u0000\u0107\u0000\u0109\u0000\u010b\u0000\u010d\u0000\u0001\u0000\u001b"+
|
||||||
|
"\u0001\u000019\u0002\u0000LLll\u0002\u0000XXxx\u0003\u000009AFaf\u0004"+
|
||||||
|
"\u000009AF__af\u0001\u000007\u0002\u000007__\u0002\u0000BBbb\u0001\u0000"+
|
||||||
|
"01\u0002\u000001__\u0004\u0000DDFFddff\u0002\u0000PPpp\u0002\u0000++-"+
|
||||||
|
"-\u0004\u0000\n\n\r\r\'\'\\\\\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000"+
|
||||||
|
"\t\t \u0002\u0000\n\n\r\r\u0003\u0000\t\n\f\r \u0002\u0000EEee\b\u0000"+
|
||||||
|
"\"\"\'\'\\\\bbffnnrrtt\u0001\u000003\u0001\u000009\u0002\u000009__\u0004"+
|
||||||
|
"\u0000$$AZ__az\u0002\u0000\u0000\u007f\u8000\ud800\u8000\udbff\u0001\u0000"+
|
||||||
|
"\u8000\ud800\u8000\udbff\u0001\u0000\u8000\udc00\u8000\udfff\u0484\u0000"+
|
||||||
|
"\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000"+
|
||||||
|
"\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000"+
|
||||||
|
"\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000="+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000A\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000\u0000\u0000K"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000O\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000\u0000Y"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000]\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0000a\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000\u0000\u0000g"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0000k\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0000m\u0001\u0000\u0000\u0000\u0000o\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000q\u0001\u0000\u0000\u0000\u0000s\u0001\u0000\u0000\u0000\u0000u"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0000w\u0001\u0000\u0000\u0000\u0000y\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0000{\u0001\u0000\u0000\u0000\u0000}\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u007f\u0001\u0000\u0000\u0000\u0000\u0081\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u0083\u0001\u0000\u0000\u0000\u0000\u0085\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u0087\u0001\u0000\u0000\u0000\u0000\u0089\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u008b\u0001\u0000\u0000\u0000\u0000\u008d\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u008f\u0001\u0000\u0000\u0000\u0000\u0091\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u0093\u0001\u0000\u0000\u0000\u0000\u0095\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u0097\u0001\u0000\u0000\u0000\u0000\u0099\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u009b\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u009f\u0001\u0000\u0000\u0000\u0000\u00a1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00a3\u0001\u0000\u0000\u0000\u0000\u00a5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00a7\u0001\u0000\u0000\u0000\u0000\u00a9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00ab\u0001\u0000\u0000\u0000\u0000\u00ad\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00af\u0001\u0000\u0000\u0000\u0000\u00b1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00b3\u0001\u0000\u0000\u0000\u0000\u00b5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00b7\u0001\u0000\u0000\u0000\u0000\u00b9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00bb\u0001\u0000\u0000\u0000\u0000\u00bd\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00bf\u0001\u0000\u0000\u0000\u0000\u00c1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00cf\u0001\u0000\u0000\u0000\u0000\u00d1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00d3\u0001\u0000\u0000\u0000\u0000\u00d5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00d7\u0001\u0000\u0000\u0000\u0000\u00d9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00db\u0001\u0000\u0000\u0000\u0000\u00dd\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00df\u0001\u0000\u0000\u0000\u0000\u00e1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00e3\u0001\u0000\u0000\u0000\u0000\u00e5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00e7\u0001\u0000\u0000\u0000\u0000\u00e9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00eb\u0001\u0000\u0000\u0000\u0000\u00ed\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00ef\u0001\u0000\u0000\u0000\u0000\u00f1\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00f3\u0001\u0000\u0000\u0000\u0000\u00f5\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00f7\u0001\u0000\u0000\u0000\u0000\u00f9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00fb\u0001\u0000\u0000\u0000\u0000\u00fd\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0000\u00ff\u0001\u0000\u0000\u0000\u0001\u010f\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0003\u0118\u0001\u0000\u0000\u0000\u0005\u011f\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0007\u0127\u0001\u0000\u0000\u0000\t\u012d\u0001\u0000\u0000\u0000\u000b"+
|
||||||
|
"\u0132\u0001\u0000\u0000\u0000\r\u0137\u0001\u0000\u0000\u0000\u000f\u013d"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0011\u0142\u0001\u0000\u0000\u0000\u0013\u0148"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0015\u014e\u0001\u0000\u0000\u0000\u0017\u0157"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0019\u015f\u0001\u0000\u0000\u0000\u001b\u0162"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u001d\u0169\u0001\u0000\u0000\u0000\u001f\u016e"+
|
||||||
|
"\u0001\u0000\u0000\u0000!\u0173\u0001\u0000\u0000\u0000#\u017b\u0001\u0000"+
|
||||||
|
"\u0000\u0000%\u0181\u0001\u0000\u0000\u0000\'\u0189\u0001\u0000\u0000"+
|
||||||
|
"\u0000)\u018f\u0001\u0000\u0000\u0000+\u0193\u0001\u0000\u0000\u0000-"+
|
||||||
|
"\u0196\u0001\u0000\u0000\u0000/\u019b\u0001\u0000\u0000\u00001\u01a6\u0001"+
|
||||||
|
"\u0000\u0000\u00003\u01ad\u0001\u0000\u0000\u00005\u01b8\u0001\u0000\u0000"+
|
||||||
|
"\u00007\u01bc\u0001\u0000\u0000\u00009\u01c6\u0001\u0000\u0000\u0000;"+
|
||||||
|
"\u01cb\u0001\u0000\u0000\u0000=\u01d2\u0001\u0000\u0000\u0000?\u01d6\u0001"+
|
||||||
|
"\u0000\u0000\u0000A\u01de\u0001\u0000\u0000\u0000C\u01e6\u0001\u0000\u0000"+
|
||||||
|
"\u0000E\u01f0\u0001\u0000\u0000\u0000G\u01f7\u0001\u0000\u0000\u0000I"+
|
||||||
|
"\u01fe\u0001\u0000\u0000\u0000K\u0204\u0001\u0000\u0000\u0000M\u020b\u0001"+
|
||||||
|
"\u0000\u0000\u0000O\u0214\u0001\u0000\u0000\u0000Q\u021a\u0001\u0000\u0000"+
|
||||||
|
"\u0000S\u0221\u0001\u0000\u0000\u0000U\u022e\u0001\u0000\u0000\u0000W"+
|
||||||
|
"\u0233\u0001\u0000\u0000\u0000Y\u0239\u0001\u0000\u0000\u0000[\u0240\u0001"+
|
||||||
|
"\u0000\u0000\u0000]\u024a\u0001\u0000\u0000\u0000_\u024e\u0001\u0000\u0000"+
|
||||||
|
"\u0000a\u0253\u0001\u0000\u0000\u0000c\u025c\u0001\u0000\u0000\u0000e"+
|
||||||
|
"\u0262\u0001\u0000\u0000\u0000g\u0269\u0001\u0000\u0000\u0000i\u026e\u0001"+
|
||||||
|
"\u0000\u0000\u0000k\u0277\u0001\u0000\u0000\u0000m\u027f\u0001\u0000\u0000"+
|
||||||
|
"\u0000o\u0285\u0001\u0000\u0000\u0000q\u0288\u0001\u0000\u0000\u0000s"+
|
||||||
|
"\u028d\u0001\u0000\u0000\u0000u\u0296\u0001\u0000\u0000\u0000w\u029b\u0001"+
|
||||||
|
"\u0000\u0000\u0000y\u02a6\u0001\u0000\u0000\u0000{\u02aa\u0001\u0000\u0000"+
|
||||||
|
"\u0000}\u02b0\u0001\u0000\u0000\u0000\u007f\u02b7\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0081\u02be\u0001\u0000\u0000\u0000\u0083\u02c6\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0085\u02de\u0001\u0000\u0000\u0000\u0087\u02e3\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0089\u02f2\u0001\u0000\u0000\u0000\u008b\u0306\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u008d\u032c\u0001\u0000\u0000\u0000\u008f\u032e\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0091\u034c\u0001\u0000\u0000\u0000\u0093\u034e\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0095\u0355\u0001\u0000\u0000\u0000\u0097\u035f\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0099\u0375\u0001\u0000\u0000\u0000\u009b\u037a\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u009d\u037c\u0001\u0000\u0000\u0000\u009f\u037e\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00a1\u0380\u0001\u0000\u0000\u0000\u00a3\u0382\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00a5\u0384\u0001\u0000\u0000\u0000\u00a7\u0386\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00a9\u0388\u0001\u0000\u0000\u0000\u00ab\u038a\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00ad\u038c\u0001\u0000\u0000\u0000\u00af\u038e\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00b1\u0390\u0001\u0000\u0000\u0000\u00b3\u0392\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00b5\u0394\u0001\u0000\u0000\u0000\u00b7\u0396\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00b9\u0398\u0001\u0000\u0000\u0000\u00bb\u039a\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00bd\u039d\u0001\u0000\u0000\u0000\u00bf\u03a0\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00c1\u03a3\u0001\u0000\u0000\u0000\u00c3\u03a6\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00c5\u03a9\u0001\u0000\u0000\u0000\u00c7\u03ac\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00c9\u03af\u0001\u0000\u0000\u0000\u00cb\u03b2\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00cd\u03b4\u0001\u0000\u0000\u0000\u00cf\u03b6\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00d1\u03b8\u0001\u0000\u0000\u0000\u00d3\u03ba\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00d5\u03bc\u0001\u0000\u0000\u0000\u00d7\u03be\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00d9\u03c0\u0001\u0000\u0000\u0000\u00db\u03c2\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00dd\u03c5\u0001\u0000\u0000\u0000\u00df\u03c8\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00e1\u03cb\u0001\u0000\u0000\u0000\u00e3\u03ce\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00e5\u03d1\u0001\u0000\u0000\u0000\u00e7\u03d4\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00e9\u03d7\u0001\u0000\u0000\u0000\u00eb\u03da\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00ed\u03de\u0001\u0000\u0000\u0000\u00ef\u03e2\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00f1\u03e7\u0001\u0000\u0000\u0000\u00f3\u03ea\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00f5\u03ed\u0001\u0000\u0000\u0000\u00f7\u03ef\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00f9\u03f4\u0001\u0000\u0000\u0000\u00fb\u03fa\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u00fd\u0408\u0001\u0000\u0000\u0000\u00ff\u0413\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0101\u041a\u0001\u0000\u0000\u0000\u0103\u0435\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0105\u0437\u0001\u0000\u0000\u0000\u0107\u0442\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0109\u0444\u0001\u0000\u0000\u0000\u010b\u0450\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u010d\u0456\u0001\u0000\u0000\u0000\u010f\u0110\u0005a\u0000\u0000\u0110"+
|
||||||
|
"\u0111\u0005b\u0000\u0000\u0111\u0112\u0005s\u0000\u0000\u0112\u0113\u0005"+
|
||||||
|
"t\u0000\u0000\u0113\u0114\u0005r\u0000\u0000\u0114\u0115\u0005a\u0000"+
|
||||||
|
"\u0000\u0115\u0116\u0005c\u0000\u0000\u0116\u0117\u0005t\u0000\u0000\u0117"+
|
||||||
|
"\u0002\u0001\u0000\u0000\u0000\u0118\u0119\u0005a\u0000\u0000\u0119\u011a"+
|
||||||
|
"\u0005s\u0000\u0000\u011a\u011b\u0005s\u0000\u0000\u011b\u011c\u0005e"+
|
||||||
|
"\u0000\u0000\u011c\u011d\u0005r\u0000\u0000\u011d\u011e\u0005t\u0000\u0000"+
|
||||||
|
"\u011e\u0004\u0001\u0000\u0000\u0000\u011f\u0120\u0005b\u0000\u0000\u0120"+
|
||||||
|
"\u0121\u0005o\u0000\u0000\u0121\u0122\u0005o\u0000\u0000\u0122\u0123\u0005"+
|
||||||
|
"l\u0000\u0000\u0123\u0124\u0005e\u0000\u0000\u0124\u0125\u0005a\u0000"+
|
||||||
|
"\u0000\u0125\u0126\u0005n\u0000\u0000\u0126\u0006\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0127\u0128\u0005b\u0000\u0000\u0128\u0129\u0005r\u0000\u0000\u0129\u012a"+
|
||||||
|
"\u0005e\u0000\u0000\u012a\u012b\u0005a\u0000\u0000\u012b\u012c\u0005k"+
|
||||||
|
"\u0000\u0000\u012c\b\u0001\u0000\u0000\u0000\u012d\u012e\u0005b\u0000"+
|
||||||
|
"\u0000\u012e\u012f\u0005y\u0000\u0000\u012f\u0130\u0005t\u0000\u0000\u0130"+
|
||||||
|
"\u0131\u0005e\u0000\u0000\u0131\n\u0001\u0000\u0000\u0000\u0132\u0133"+
|
||||||
|
"\u0005c\u0000\u0000\u0133\u0134\u0005a\u0000\u0000\u0134\u0135\u0005s"+
|
||||||
|
"\u0000\u0000\u0135\u0136\u0005e\u0000\u0000\u0136\f\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0137\u0138\u0005c\u0000\u0000\u0138\u0139\u0005a\u0000\u0000\u0139"+
|
||||||
|
"\u013a\u0005t\u0000\u0000\u013a\u013b\u0005c\u0000\u0000\u013b\u013c\u0005"+
|
||||||
|
"h\u0000\u0000\u013c\u000e\u0001\u0000\u0000\u0000\u013d\u013e\u0005c\u0000"+
|
||||||
|
"\u0000\u013e\u013f\u0005h\u0000\u0000\u013f\u0140\u0005a\u0000\u0000\u0140"+
|
||||||
|
"\u0141\u0005r\u0000\u0000\u0141\u0010\u0001\u0000\u0000\u0000\u0142\u0143"+
|
||||||
|
"\u0005c\u0000\u0000\u0143\u0144\u0005l\u0000\u0000\u0144\u0145\u0005a"+
|
||||||
|
"\u0000\u0000\u0145\u0146\u0005s\u0000\u0000\u0146\u0147\u0005s\u0000\u0000"+
|
||||||
|
"\u0147\u0012\u0001\u0000\u0000\u0000\u0148\u0149\u0005c\u0000\u0000\u0149"+
|
||||||
|
"\u014a\u0005o\u0000\u0000\u014a\u014b\u0005n\u0000\u0000\u014b\u014c\u0005"+
|
||||||
|
"s\u0000\u0000\u014c\u014d\u0005t\u0000\u0000\u014d\u0014\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u014e\u014f\u0005c\u0000\u0000\u014f\u0150\u0005o\u0000\u0000\u0150"+
|
||||||
|
"\u0151\u0005n\u0000\u0000\u0151\u0152\u0005t\u0000\u0000\u0152\u0153\u0005"+
|
||||||
|
"i\u0000\u0000\u0153\u0154\u0005n\u0000\u0000\u0154\u0155\u0005u\u0000"+
|
||||||
|
"\u0000\u0155\u0156\u0005e\u0000\u0000\u0156\u0016\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0157\u0158\u0005d\u0000\u0000\u0158\u0159\u0005e\u0000\u0000\u0159\u015a"+
|
||||||
|
"\u0005f\u0000\u0000\u015a\u015b\u0005a\u0000\u0000\u015b\u015c\u0005u"+
|
||||||
|
"\u0000\u0000\u015c\u015d\u0005l\u0000\u0000\u015d\u015e\u0005t\u0000\u0000"+
|
||||||
|
"\u015e\u0018\u0001\u0000\u0000\u0000\u015f\u0160\u0005d\u0000\u0000\u0160"+
|
||||||
|
"\u0161\u0005o\u0000\u0000\u0161\u001a\u0001\u0000\u0000\u0000\u0162\u0163"+
|
||||||
|
"\u0005d\u0000\u0000\u0163\u0164\u0005o\u0000\u0000\u0164\u0165\u0005u"+
|
||||||
|
"\u0000\u0000\u0165\u0166\u0005b\u0000\u0000\u0166\u0167\u0005l\u0000\u0000"+
|
||||||
|
"\u0167\u0168\u0005e\u0000\u0000\u0168\u001c\u0001\u0000\u0000\u0000\u0169"+
|
||||||
|
"\u016a\u0005e\u0000\u0000\u016a\u016b\u0005l\u0000\u0000\u016b\u016c\u0005"+
|
||||||
|
"s\u0000\u0000\u016c\u016d\u0005e\u0000\u0000\u016d\u001e\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u016e\u016f\u0005e\u0000\u0000\u016f\u0170\u0005n\u0000\u0000\u0170"+
|
||||||
|
"\u0171\u0005u\u0000\u0000\u0171\u0172\u0005m\u0000\u0000\u0172 \u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0173\u0174\u0005e\u0000\u0000\u0174\u0175\u0005x\u0000"+
|
||||||
|
"\u0000\u0175\u0176\u0005t\u0000\u0000\u0176\u0177\u0005e\u0000\u0000\u0177"+
|
||||||
|
"\u0178\u0005n\u0000\u0000\u0178\u0179\u0005d\u0000\u0000\u0179\u017a\u0005"+
|
||||||
|
"s\u0000\u0000\u017a\"\u0001\u0000\u0000\u0000\u017b\u017c\u0005f\u0000"+
|
||||||
|
"\u0000\u017c\u017d\u0005i\u0000\u0000\u017d\u017e\u0005n\u0000\u0000\u017e"+
|
||||||
|
"\u017f\u0005a\u0000\u0000\u017f\u0180\u0005l\u0000\u0000\u0180$\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0181\u0182\u0005f\u0000\u0000\u0182\u0183\u0005i\u0000"+
|
||||||
|
"\u0000\u0183\u0184\u0005n\u0000\u0000\u0184\u0185\u0005a\u0000\u0000\u0185"+
|
||||||
|
"\u0186\u0005l\u0000\u0000\u0186\u0187\u0005l\u0000\u0000\u0187\u0188\u0005"+
|
||||||
|
"y\u0000\u0000\u0188&\u0001\u0000\u0000\u0000\u0189\u018a\u0005f\u0000"+
|
||||||
|
"\u0000\u018a\u018b\u0005l\u0000\u0000\u018b\u018c\u0005o\u0000\u0000\u018c"+
|
||||||
|
"\u018d\u0005a\u0000\u0000\u018d\u018e\u0005t\u0000\u0000\u018e(\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u018f\u0190\u0005f\u0000\u0000\u0190\u0191\u0005o\u0000"+
|
||||||
|
"\u0000\u0191\u0192\u0005r\u0000\u0000\u0192*\u0001\u0000\u0000\u0000\u0193"+
|
||||||
|
"\u0194\u0005i\u0000\u0000\u0194\u0195\u0005f\u0000\u0000\u0195,\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0196\u0197\u0005g\u0000\u0000\u0197\u0198\u0005o\u0000"+
|
||||||
|
"\u0000\u0198\u0199\u0005t\u0000\u0000\u0199\u019a\u0005o\u0000\u0000\u019a"+
|
||||||
|
".\u0001\u0000\u0000\u0000\u019b\u019c\u0005i\u0000\u0000\u019c\u019d\u0005"+
|
||||||
|
"m\u0000\u0000\u019d\u019e\u0005p\u0000\u0000\u019e\u019f\u0005l\u0000"+
|
||||||
|
"\u0000\u019f\u01a0\u0005e\u0000\u0000\u01a0\u01a1\u0005m\u0000\u0000\u01a1"+
|
||||||
|
"\u01a2\u0005e\u0000\u0000\u01a2\u01a3\u0005n\u0000\u0000\u01a3\u01a4\u0005"+
|
||||||
|
"t\u0000\u0000\u01a4\u01a5\u0005s\u0000\u0000\u01a50\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u01a6\u01a7\u0005i\u0000\u0000\u01a7\u01a8\u0005m\u0000\u0000\u01a8"+
|
||||||
|
"\u01a9\u0005p\u0000\u0000\u01a9\u01aa\u0005o\u0000\u0000\u01aa\u01ab\u0005"+
|
||||||
|
"r\u0000\u0000\u01ab\u01ac\u0005t\u0000\u0000\u01ac2\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u01ad\u01ae\u0005i\u0000\u0000\u01ae\u01af\u0005n\u0000\u0000\u01af"+
|
||||||
|
"\u01b0\u0005s\u0000\u0000\u01b0\u01b1\u0005t\u0000\u0000\u01b1\u01b2\u0005"+
|
||||||
|
"a\u0000\u0000\u01b2\u01b3\u0005n\u0000\u0000\u01b3\u01b4\u0005c\u0000"+
|
||||||
|
"\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0005o\u0000\u0000\u01b6"+
|
||||||
|
"\u01b7\u0005f\u0000\u0000\u01b74\u0001\u0000\u0000\u0000\u01b8\u01b9\u0005"+
|
||||||
|
"i\u0000\u0000\u01b9\u01ba\u0005n\u0000\u0000\u01ba\u01bb\u0005t\u0000"+
|
||||||
|
"\u0000\u01bb6\u0001\u0000\u0000\u0000\u01bc\u01bd\u0005i\u0000\u0000\u01bd"+
|
||||||
|
"\u01be\u0005n\u0000\u0000\u01be\u01bf\u0005t\u0000\u0000\u01bf\u01c0\u0005"+
|
||||||
|
"e\u0000\u0000\u01c0\u01c1\u0005r\u0000\u0000\u01c1\u01c2\u0005f\u0000"+
|
||||||
|
"\u0000\u01c2\u01c3\u0005a\u0000\u0000\u01c3\u01c4\u0005c\u0000\u0000\u01c4"+
|
||||||
|
"\u01c5\u0005e\u0000\u0000\u01c58\u0001\u0000\u0000\u0000\u01c6\u01c7\u0005"+
|
||||||
|
"l\u0000\u0000\u01c7\u01c8\u0005o\u0000\u0000\u01c8\u01c9\u0005n\u0000"+
|
||||||
|
"\u0000\u01c9\u01ca\u0005g\u0000\u0000\u01ca:\u0001\u0000\u0000\u0000\u01cb"+
|
||||||
|
"\u01cc\u0005n\u0000\u0000\u01cc\u01cd\u0005a\u0000\u0000\u01cd\u01ce\u0005"+
|
||||||
|
"t\u0000\u0000\u01ce\u01cf\u0005i\u0000\u0000\u01cf\u01d0\u0005v\u0000"+
|
||||||
|
"\u0000\u01d0\u01d1\u0005e\u0000\u0000\u01d1<\u0001\u0000\u0000\u0000\u01d2"+
|
||||||
|
"\u01d3\u0005n\u0000\u0000\u01d3\u01d4\u0005e\u0000\u0000\u01d4\u01d5\u0005"+
|
||||||
|
"w\u0000\u0000\u01d5>\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005p\u0000"+
|
||||||
|
"\u0000\u01d7\u01d8\u0005a\u0000\u0000\u01d8\u01d9\u0005c\u0000\u0000\u01d9"+
|
||||||
|
"\u01da\u0005k\u0000\u0000\u01da\u01db\u0005a\u0000\u0000\u01db\u01dc\u0005"+
|
||||||
|
"g\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01dd@\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u01de\u01df\u0005p\u0000\u0000\u01df\u01e0\u0005r\u0000\u0000\u01e0"+
|
||||||
|
"\u01e1\u0005i\u0000\u0000\u01e1\u01e2\u0005v\u0000\u0000\u01e2\u01e3\u0005"+
|
||||||
|
"a\u0000\u0000\u01e3\u01e4\u0005t\u0000\u0000\u01e4\u01e5\u0005e\u0000"+
|
||||||
|
"\u0000\u01e5B\u0001\u0000\u0000\u0000\u01e6\u01e7\u0005p\u0000\u0000\u01e7"+
|
||||||
|
"\u01e8\u0005r\u0000\u0000\u01e8\u01e9\u0005o\u0000\u0000\u01e9\u01ea\u0005"+
|
||||||
|
"t\u0000\u0000\u01ea\u01eb\u0005e\u0000\u0000\u01eb\u01ec\u0005c\u0000"+
|
||||||
|
"\u0000\u01ec\u01ed\u0005t\u0000\u0000\u01ed\u01ee\u0005e\u0000\u0000\u01ee"+
|
||||||
|
"\u01ef\u0005d\u0000\u0000\u01efD\u0001\u0000\u0000\u0000\u01f0\u01f1\u0005"+
|
||||||
|
"p\u0000\u0000\u01f1\u01f2\u0005u\u0000\u0000\u01f2\u01f3\u0005b\u0000"+
|
||||||
|
"\u0000\u01f3\u01f4\u0005l\u0000\u0000\u01f4\u01f5\u0005i\u0000\u0000\u01f5"+
|
||||||
|
"\u01f6\u0005c\u0000\u0000\u01f6F\u0001\u0000\u0000\u0000\u01f7\u01f8\u0005"+
|
||||||
|
"r\u0000\u0000\u01f8\u01f9\u0005e\u0000\u0000\u01f9\u01fa\u0005t\u0000"+
|
||||||
|
"\u0000\u01fa\u01fb\u0005u\u0000\u0000\u01fb\u01fc\u0005r\u0000\u0000\u01fc"+
|
||||||
|
"\u01fd\u0005n\u0000\u0000\u01fdH\u0001\u0000\u0000\u0000\u01fe\u01ff\u0005"+
|
||||||
|
"s\u0000\u0000\u01ff\u0200\u0005h\u0000\u0000\u0200\u0201\u0005o\u0000"+
|
||||||
|
"\u0000\u0201\u0202\u0005r\u0000\u0000\u0202\u0203\u0005t\u0000\u0000\u0203"+
|
||||||
|
"J\u0001\u0000\u0000\u0000\u0204\u0205\u0005s\u0000\u0000\u0205\u0206\u0005"+
|
||||||
|
"t\u0000\u0000\u0206\u0207\u0005a\u0000\u0000\u0207\u0208\u0005t\u0000"+
|
||||||
|
"\u0000\u0208\u0209\u0005i\u0000\u0000\u0209\u020a\u0005c\u0000\u0000\u020a"+
|
||||||
|
"L\u0001\u0000\u0000\u0000\u020b\u020c\u0005s\u0000\u0000\u020c\u020d\u0005"+
|
||||||
|
"t\u0000\u0000\u020d\u020e\u0005r\u0000\u0000\u020e\u020f\u0005i\u0000"+
|
||||||
|
"\u0000\u020f\u0210\u0005c\u0000\u0000\u0210\u0211\u0005t\u0000\u0000\u0211"+
|
||||||
|
"\u0212\u0005f\u0000\u0000\u0212\u0213\u0005p\u0000\u0000\u0213N\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0214\u0215\u0005s\u0000\u0000\u0215\u0216\u0005u\u0000"+
|
||||||
|
"\u0000\u0216\u0217\u0005p\u0000\u0000\u0217\u0218\u0005e\u0000\u0000\u0218"+
|
||||||
|
"\u0219\u0005r\u0000\u0000\u0219P\u0001\u0000\u0000\u0000\u021a\u021b\u0005"+
|
||||||
|
"s\u0000\u0000\u021b\u021c\u0005w\u0000\u0000\u021c\u021d\u0005i\u0000"+
|
||||||
|
"\u0000\u021d\u021e\u0005t\u0000\u0000\u021e\u021f\u0005c\u0000\u0000\u021f"+
|
||||||
|
"\u0220\u0005h\u0000\u0000\u0220R\u0001\u0000\u0000\u0000\u0221\u0222\u0005"+
|
||||||
|
"s\u0000\u0000\u0222\u0223\u0005y\u0000\u0000\u0223\u0224\u0005n\u0000"+
|
||||||
|
"\u0000\u0224\u0225\u0005c\u0000\u0000\u0225\u0226\u0005h\u0000\u0000\u0226"+
|
||||||
|
"\u0227\u0005r\u0000\u0000\u0227\u0228\u0005o\u0000\u0000\u0228\u0229\u0005"+
|
||||||
|
"n\u0000\u0000\u0229\u022a\u0005i\u0000\u0000\u022a\u022b\u0005z\u0000"+
|
||||||
|
"\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u022d\u0005d\u0000\u0000\u022d"+
|
||||||
|
"T\u0001\u0000\u0000\u0000\u022e\u022f\u0005t\u0000\u0000\u022f\u0230\u0005"+
|
||||||
|
"h\u0000\u0000\u0230\u0231\u0005i\u0000\u0000\u0231\u0232\u0005s\u0000"+
|
||||||
|
"\u0000\u0232V\u0001\u0000\u0000\u0000\u0233\u0234\u0005t\u0000\u0000\u0234"+
|
||||||
|
"\u0235\u0005h\u0000\u0000\u0235\u0236\u0005r\u0000\u0000\u0236\u0237\u0005"+
|
||||||
|
"o\u0000\u0000\u0237\u0238\u0005w\u0000\u0000\u0238X\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0239\u023a\u0005t\u0000\u0000\u023a\u023b\u0005h\u0000\u0000\u023b"+
|
||||||
|
"\u023c\u0005r\u0000\u0000\u023c\u023d\u0005o\u0000\u0000\u023d\u023e\u0005"+
|
||||||
|
"w\u0000\u0000\u023e\u023f\u0005s\u0000\u0000\u023fZ\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0240\u0241\u0005t\u0000\u0000\u0241\u0242\u0005r\u0000\u0000\u0242"+
|
||||||
|
"\u0243\u0005a\u0000\u0000\u0243\u0244\u0005n\u0000\u0000\u0244\u0245\u0005"+
|
||||||
|
"s\u0000\u0000\u0245\u0246\u0005i\u0000\u0000\u0246\u0247\u0005e\u0000"+
|
||||||
|
"\u0000\u0247\u0248\u0005n\u0000\u0000\u0248\u0249\u0005t\u0000\u0000\u0249"+
|
||||||
|
"\\\u0001\u0000\u0000\u0000\u024a\u024b\u0005t\u0000\u0000\u024b\u024c"+
|
||||||
|
"\u0005r\u0000\u0000\u024c\u024d\u0005y\u0000\u0000\u024d^\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u024e\u024f\u0005v\u0000\u0000\u024f\u0250\u0005o\u0000\u0000"+
|
||||||
|
"\u0250\u0251\u0005i\u0000\u0000\u0251\u0252\u0005d\u0000\u0000\u0252`"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0253\u0254\u0005v\u0000\u0000\u0254\u0255\u0005"+
|
||||||
|
"o\u0000\u0000\u0255\u0256\u0005l\u0000\u0000\u0256\u0257\u0005a\u0000"+
|
||||||
|
"\u0000\u0257\u0258\u0005t\u0000\u0000\u0258\u0259\u0005i\u0000\u0000\u0259"+
|
||||||
|
"\u025a\u0005l\u0000\u0000\u025a\u025b\u0005e\u0000\u0000\u025bb\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u025c\u025d\u0005w\u0000\u0000\u025d\u025e\u0005h\u0000"+
|
||||||
|
"\u0000\u025e\u025f\u0005i\u0000\u0000\u025f\u0260\u0005l\u0000\u0000\u0260"+
|
||||||
|
"\u0261\u0005e\u0000\u0000\u0261d\u0001\u0000\u0000\u0000\u0262\u0263\u0005"+
|
||||||
|
"m\u0000\u0000\u0263\u0264\u0005o\u0000\u0000\u0264\u0265\u0005d\u0000"+
|
||||||
|
"\u0000\u0265\u0266\u0005u\u0000\u0000\u0266\u0267\u0005l\u0000\u0000\u0267"+
|
||||||
|
"\u0268\u0005e\u0000\u0000\u0268f\u0001\u0000\u0000\u0000\u0269\u026a\u0005"+
|
||||||
|
"o\u0000\u0000\u026a\u026b\u0005p\u0000\u0000\u026b\u026c\u0005e\u0000"+
|
||||||
|
"\u0000\u026c\u026d\u0005n\u0000\u0000\u026dh\u0001\u0000\u0000\u0000\u026e"+
|
||||||
|
"\u026f\u0005r\u0000\u0000\u026f\u0270\u0005e\u0000\u0000\u0270\u0271\u0005"+
|
||||||
|
"q\u0000\u0000\u0271\u0272\u0005u\u0000\u0000\u0272\u0273\u0005i\u0000"+
|
||||||
|
"\u0000\u0273\u0274\u0005r\u0000\u0000\u0274\u0275\u0005e\u0000\u0000\u0275"+
|
||||||
|
"\u0276\u0005s\u0000\u0000\u0276j\u0001\u0000\u0000\u0000\u0277\u0278\u0005"+
|
||||||
|
"e\u0000\u0000\u0278\u0279\u0005x\u0000\u0000\u0279\u027a\u0005p\u0000"+
|
||||||
|
"\u0000\u027a\u027b\u0005o\u0000\u0000\u027b\u027c\u0005r\u0000\u0000\u027c"+
|
||||||
|
"\u027d\u0005t\u0000\u0000\u027d\u027e\u0005s\u0000\u0000\u027el\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u027f\u0280\u0005o\u0000\u0000\u0280\u0281\u0005p\u0000"+
|
||||||
|
"\u0000\u0281\u0282\u0005e\u0000\u0000\u0282\u0283\u0005n\u0000\u0000\u0283"+
|
||||||
|
"\u0284\u0005s\u0000\u0000\u0284n\u0001\u0000\u0000\u0000\u0285\u0286\u0005"+
|
||||||
|
"t\u0000\u0000\u0286\u0287\u0005o\u0000\u0000\u0287p\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0288\u0289\u0005u\u0000\u0000\u0289\u028a\u0005s\u0000\u0000\u028a"+
|
||||||
|
"\u028b\u0005e\u0000\u0000\u028b\u028c\u0005s\u0000\u0000\u028cr\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u028d\u028e\u0005p\u0000\u0000\u028e\u028f\u0005r\u0000"+
|
||||||
|
"\u0000\u028f\u0290\u0005o\u0000\u0000\u0290\u0291\u0005v\u0000\u0000\u0291"+
|
||||||
|
"\u0292\u0005i\u0000\u0000\u0292\u0293\u0005d\u0000\u0000\u0293\u0294\u0005"+
|
||||||
|
"e\u0000\u0000\u0294\u0295\u0005s\u0000\u0000\u0295t\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0296\u0297\u0005w\u0000\u0000\u0297\u0298\u0005i\u0000\u0000\u0298"+
|
||||||
|
"\u0299\u0005t\u0000\u0000\u0299\u029a\u0005h\u0000\u0000\u029av\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u029b\u029c\u0005t\u0000\u0000\u029c\u029d\u0005r\u0000"+
|
||||||
|
"\u0000\u029d\u029e\u0005a\u0000\u0000\u029e\u029f\u0005n\u0000\u0000\u029f"+
|
||||||
|
"\u02a0\u0005s\u0000\u0000\u02a0\u02a1\u0005i\u0000\u0000\u02a1\u02a2\u0005"+
|
||||||
|
"t\u0000\u0000\u02a2\u02a3\u0005i\u0000\u0000\u02a3\u02a4\u0005v\u0000"+
|
||||||
|
"\u0000\u02a4\u02a5\u0005e\u0000\u0000\u02a5x\u0001\u0000\u0000\u0000\u02a6"+
|
||||||
|
"\u02a7\u0005v\u0000\u0000\u02a7\u02a8\u0005a\u0000\u0000\u02a8\u02a9\u0005"+
|
||||||
|
"r\u0000\u0000\u02a9z\u0001\u0000\u0000\u0000\u02aa\u02ab\u0005y\u0000"+
|
||||||
|
"\u0000\u02ab\u02ac\u0005i\u0000\u0000\u02ac\u02ad\u0005e\u0000\u0000\u02ad"+
|
||||||
|
"\u02ae\u0005l\u0000\u0000\u02ae\u02af\u0005d\u0000\u0000\u02af|\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02b0\u02b1\u0005r\u0000\u0000\u02b1\u02b2\u0005e\u0000"+
|
||||||
|
"\u0000\u02b2\u02b3\u0005c\u0000\u0000\u02b3\u02b4\u0005o\u0000\u0000\u02b4"+
|
||||||
|
"\u02b5\u0005r\u0000\u0000\u02b5\u02b6\u0005d\u0000\u0000\u02b6~\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02b7\u02b8\u0005s\u0000\u0000\u02b8\u02b9\u0005e\u0000"+
|
||||||
|
"\u0000\u02b9\u02ba\u0005a\u0000\u0000\u02ba\u02bb\u0005l\u0000\u0000\u02bb"+
|
||||||
|
"\u02bc\u0005e\u0000\u0000\u02bc\u02bd\u0005d\u0000\u0000\u02bd\u0080\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02be\u02bf\u0005p\u0000\u0000\u02bf\u02c0\u0005e\u0000"+
|
||||||
|
"\u0000\u02c0\u02c1\u0005r\u0000\u0000\u02c1\u02c2\u0005m\u0000\u0000\u02c2"+
|
||||||
|
"\u02c3\u0005i\u0000\u0000\u02c3\u02c4\u0005t\u0000\u0000\u02c4\u02c5\u0005"+
|
||||||
|
"s\u0000\u0000\u02c5\u0082\u0001\u0000\u0000\u0000\u02c6\u02c7\u0005n\u0000"+
|
||||||
|
"\u0000\u02c7\u02c8\u0005o\u0000\u0000\u02c8\u02c9\u0005n\u0000\u0000\u02c9"+
|
||||||
|
"\u02ca\u0005-\u0000\u0000\u02ca\u02cb\u0005s\u0000\u0000\u02cb\u02cc\u0005"+
|
||||||
|
"e\u0000\u0000\u02cc\u02cd\u0005a\u0000\u0000\u02cd\u02ce\u0005l\u0000"+
|
||||||
|
"\u0000\u02ce\u02cf\u0005e\u0000\u0000\u02cf\u02d0\u0005d\u0000\u0000\u02d0"+
|
||||||
|
"\u0084\u0001\u0000\u0000\u0000\u02d1\u02df\u00050\u0000\u0000\u02d2\u02dc"+
|
||||||
|
"\u0007\u0000\u0000\u0000\u02d3\u02d5\u0003\u0109\u0084\u0000\u02d4\u02d3"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u02d4\u02d5\u0001\u0000\u0000\u0000\u02d5\u02dd"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u02d6\u02d8\u0005_\u0000\u0000\u02d7\u02d6\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02d8\u02d9\u0001\u0000\u0000\u0000\u02d9\u02d7\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02d9\u02da\u0001\u0000\u0000\u0000\u02da\u02db\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02db\u02dd\u0003\u0109\u0084\u0000\u02dc\u02d4\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02dc\u02d7\u0001\u0000\u0000\u0000\u02dd\u02df\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02de\u02d1\u0001\u0000\u0000\u0000\u02de\u02d2\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02df\u02e1\u0001\u0000\u0000\u0000\u02e0\u02e2\u0007"+
|
||||||
|
"\u0001\u0000\u0000\u02e1\u02e0\u0001\u0000\u0000\u0000\u02e1\u02e2\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u02e2\u0086\u0001\u0000\u0000\u0000\u02e3\u02e4\u0005"+
|
||||||
|
"0\u0000\u0000\u02e4\u02e5\u0007\u0002\u0000\u0000\u02e5\u02ed\u0007\u0003"+
|
||||||
|
"\u0000\u0000\u02e6\u02e8\u0007\u0004\u0000\u0000\u02e7\u02e6\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u02e8\u02eb\u0001\u0000\u0000\u0000\u02e9\u02e7\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u02e9\u02ea\u0001\u0000\u0000\u0000\u02ea\u02ec\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u02eb\u02e9\u0001\u0000\u0000\u0000\u02ec\u02ee\u0007\u0003"+
|
||||||
|
"\u0000\u0000\u02ed\u02e9\u0001\u0000\u0000\u0000\u02ed\u02ee\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u02ee\u02f0\u0001\u0000\u0000\u0000\u02ef\u02f1\u0007\u0001"+
|
||||||
|
"\u0000\u0000\u02f0\u02ef\u0001\u0000\u0000\u0000\u02f0\u02f1\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u02f1\u0088\u0001\u0000\u0000\u0000\u02f2\u02f6\u00050\u0000"+
|
||||||
|
"\u0000\u02f3\u02f5\u0005_\u0000\u0000\u02f4\u02f3\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02f5\u02f8\u0001\u0000\u0000\u0000\u02f6\u02f4\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02f6\u02f7\u0001\u0000\u0000\u0000\u02f7\u02f9\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02f8\u02f6\u0001\u0000\u0000\u0000\u02f9\u0301\u0007\u0005\u0000\u0000"+
|
||||||
|
"\u02fa\u02fc\u0007\u0006\u0000\u0000\u02fb\u02fa\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02fc\u02ff\u0001\u0000\u0000\u0000\u02fd\u02fb\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02fd\u02fe\u0001\u0000\u0000\u0000\u02fe\u0300\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u02ff\u02fd\u0001\u0000\u0000\u0000\u0300\u0302\u0007\u0005\u0000\u0000"+
|
||||||
|
"\u0301\u02fd\u0001\u0000\u0000\u0000\u0301\u0302\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0302\u0304\u0001\u0000\u0000\u0000\u0303\u0305\u0007\u0001\u0000\u0000"+
|
||||||
|
"\u0304\u0303\u0001\u0000\u0000\u0000\u0304\u0305\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0305\u008a\u0001\u0000\u0000\u0000\u0306\u0307\u00050\u0000\u0000\u0307"+
|
||||||
|
"\u0308\u0007\u0007\u0000\u0000\u0308\u0310\u0007\b\u0000\u0000\u0309\u030b"+
|
||||||
|
"\u0007\t\u0000\u0000\u030a\u0309\u0001\u0000\u0000\u0000\u030b\u030e\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u030c\u030a\u0001\u0000\u0000\u0000\u030c\u030d\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u030d\u030f\u0001\u0000\u0000\u0000\u030e\u030c\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u030f\u0311\u0007\b\u0000\u0000\u0310\u030c\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0310\u0311\u0001\u0000\u0000\u0000\u0311\u0313\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0312\u0314\u0007\u0001\u0000\u0000\u0313\u0312\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0313\u0314\u0001\u0000\u0000\u0000\u0314\u008c\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0315\u0316\u0003\u0109\u0084\u0000\u0316\u0318\u0005.\u0000"+
|
||||||
|
"\u0000\u0317\u0319\u0003\u0109\u0084\u0000\u0318\u0317\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0318\u0319\u0001\u0000\u0000\u0000\u0319\u031d\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u031a\u031b\u0005.\u0000\u0000\u031b\u031d\u0003\u0109\u0084\u0000"+
|
||||||
|
"\u031c\u0315\u0001\u0000\u0000\u0000\u031c\u031a\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u031d\u031f\u0001\u0000\u0000\u0000\u031e\u0320\u0003\u0101\u0080\u0000"+
|
||||||
|
"\u031f\u031e\u0001\u0000\u0000\u0000\u031f\u0320\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0320\u0322\u0001\u0000\u0000\u0000\u0321\u0323\u0007\n\u0000\u0000\u0322"+
|
||||||
|
"\u0321\u0001\u0000\u0000\u0000\u0322\u0323\u0001\u0000\u0000\u0000\u0323"+
|
||||||
|
"\u032d\u0001\u0000\u0000\u0000\u0324\u032a\u0003\u0109\u0084\u0000\u0325"+
|
||||||
|
"\u0327\u0003\u0101\u0080\u0000\u0326\u0328\u0007\n\u0000\u0000\u0327\u0326"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0327\u0328\u0001\u0000\u0000\u0000\u0328\u032b"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0329\u032b\u0007\n\u0000\u0000\u032a\u0325\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u032a\u0329\u0001\u0000\u0000\u0000\u032b\u032d\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u032c\u031c\u0001\u0000\u0000\u0000\u032c\u0324\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u032d\u008e\u0001\u0000\u0000\u0000\u032e\u032f\u0005"+
|
||||||
|
"0\u0000\u0000\u032f\u0339\u0007\u0002\u0000\u0000\u0330\u0332\u0003\u0105"+
|
||||||
|
"\u0082\u0000\u0331\u0333\u0005.\u0000\u0000\u0332\u0331\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0332\u0333\u0001\u0000\u0000\u0000\u0333\u033a\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0334\u0336\u0003\u0105\u0082\u0000\u0335\u0334\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0335\u0336\u0001\u0000\u0000\u0000\u0336\u0337\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0337\u0338\u0005.\u0000\u0000\u0338\u033a\u0003\u0105\u0082\u0000"+
|
||||||
|
"\u0339\u0330\u0001\u0000\u0000\u0000\u0339\u0335\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u033a\u033b\u0001\u0000\u0000\u0000\u033b\u033d\u0007\u000b\u0000\u0000"+
|
||||||
|
"\u033c\u033e\u0007\f\u0000\u0000\u033d\u033c\u0001\u0000\u0000\u0000\u033d"+
|
||||||
|
"\u033e\u0001\u0000\u0000\u0000\u033e\u033f\u0001\u0000\u0000\u0000\u033f"+
|
||||||
|
"\u0341\u0003\u0109\u0084\u0000\u0340\u0342\u0007\n\u0000\u0000\u0341\u0340"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0341\u0342\u0001\u0000\u0000\u0000\u0342\u0090"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0343\u0344\u0005t\u0000\u0000\u0344\u0345\u0005"+
|
||||||
|
"r\u0000\u0000\u0345\u0346\u0005u\u0000\u0000\u0346\u034d\u0005e\u0000"+
|
||||||
|
"\u0000\u0347\u0348\u0005f\u0000\u0000\u0348\u0349\u0005a\u0000\u0000\u0349"+
|
||||||
|
"\u034a\u0005l\u0000\u0000\u034a\u034b\u0005s\u0000\u0000\u034b\u034d\u0005"+
|
||||||
|
"e\u0000\u0000\u034c\u0343\u0001\u0000\u0000\u0000\u034c\u0347\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u034d\u0092\u0001\u0000\u0000\u0000\u034e\u0351\u0005\'\u0000"+
|
||||||
|
"\u0000\u034f\u0352\b\r\u0000\u0000\u0350\u0352\u0003\u0103\u0081\u0000"+
|
||||||
|
"\u0351\u034f\u0001\u0000\u0000\u0000\u0351\u0350\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0352\u0353\u0001\u0000\u0000\u0000\u0353\u0354\u0005\'\u0000\u0000\u0354"+
|
||||||
|
"\u0094\u0001\u0000\u0000\u0000\u0355\u035a\u0005\"\u0000\u0000\u0356\u0359"+
|
||||||
|
"\b\u000e\u0000\u0000\u0357\u0359\u0003\u0103\u0081\u0000\u0358\u0356\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0358\u0357\u0001\u0000\u0000\u0000\u0359\u035c\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u035a\u0358\u0001\u0000\u0000\u0000\u035a\u035b\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u035b\u035d\u0001\u0000\u0000\u0000\u035c\u035a\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u035d\u035e\u0005\"\u0000\u0000\u035e\u0096\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u035f\u0360\u0005\"\u0000\u0000\u0360\u0361\u0005\"\u0000"+
|
||||||
|
"\u0000\u0361\u0362\u0005\"\u0000\u0000\u0362\u0366\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0363\u0365\u0007\u000f\u0000\u0000\u0364\u0363\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0365\u0368\u0001\u0000\u0000\u0000\u0366\u0364\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0366\u0367\u0001\u0000\u0000\u0000\u0367\u0369\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0368\u0366\u0001\u0000\u0000\u0000\u0369\u036e\u0007\u0010\u0000\u0000"+
|
||||||
|
"\u036a\u036d\t\u0000\u0000\u0000\u036b\u036d\u0003\u0103\u0081\u0000\u036c"+
|
||||||
|
"\u036a\u0001\u0000\u0000\u0000\u036c\u036b\u0001\u0000\u0000\u0000\u036d"+
|
||||||
|
"\u0370\u0001\u0000\u0000\u0000\u036e\u036f\u0001\u0000\u0000\u0000\u036e"+
|
||||||
|
"\u036c\u0001\u0000\u0000\u0000\u036f\u0371\u0001\u0000\u0000\u0000\u0370"+
|
||||||
|
"\u036e\u0001\u0000\u0000\u0000\u0371\u0372\u0005\"\u0000\u0000\u0372\u0373"+
|
||||||
|
"\u0005\"\u0000\u0000\u0373\u0374\u0005\"\u0000\u0000\u0374\u0098\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0375\u0376\u0005n\u0000\u0000\u0376\u0377\u0005u\u0000"+
|
||||||
|
"\u0000\u0377\u0378\u0005l\u0000\u0000\u0378\u0379\u0005l\u0000\u0000\u0379"+
|
||||||
|
"\u009a\u0001\u0000\u0000\u0000\u037a\u037b\u0005(\u0000\u0000\u037b\u009c"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u037c\u037d\u0005)\u0000\u0000\u037d\u009e\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u037e\u037f\u0005{\u0000\u0000\u037f\u00a0\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0380\u0381\u0005}\u0000\u0000\u0381\u00a2\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0382\u0383\u0005[\u0000\u0000\u0383\u00a4\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0384\u0385\u0005]\u0000\u0000\u0385\u00a6\u0001\u0000\u0000\u0000\u0386"+
|
||||||
|
"\u0387\u0005;\u0000\u0000\u0387\u00a8\u0001\u0000\u0000\u0000\u0388\u0389"+
|
||||||
|
"\u0005,\u0000\u0000\u0389\u00aa\u0001\u0000\u0000\u0000\u038a\u038b\u0005"+
|
||||||
|
".\u0000\u0000\u038b\u00ac\u0001\u0000\u0000\u0000\u038c\u038d\u0005=\u0000"+
|
||||||
|
"\u0000\u038d\u00ae\u0001\u0000\u0000\u0000\u038e\u038f\u0005>\u0000\u0000"+
|
||||||
|
"\u038f\u00b0\u0001\u0000\u0000\u0000\u0390\u0391\u0005<\u0000\u0000\u0391"+
|
||||||
|
"\u00b2\u0001\u0000\u0000\u0000\u0392\u0393\u0005!\u0000\u0000\u0393\u00b4"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u0394\u0395\u0005~\u0000\u0000\u0395\u00b6\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0396\u0397\u0005?\u0000\u0000\u0397\u00b8\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0398\u0399\u0005:\u0000\u0000\u0399\u00ba\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u039a\u039b\u0005=\u0000\u0000\u039b\u039c\u0005=\u0000\u0000\u039c"+
|
||||||
|
"\u00bc\u0001\u0000\u0000\u0000\u039d\u039e\u0005<\u0000\u0000\u039e\u039f"+
|
||||||
|
"\u0005=\u0000\u0000\u039f\u00be\u0001\u0000\u0000\u0000\u03a0\u03a1\u0005"+
|
||||||
|
">\u0000\u0000\u03a1\u03a2\u0005=\u0000\u0000\u03a2\u00c0\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03a3\u03a4\u0005!\u0000\u0000\u03a4\u03a5\u0005=\u0000\u0000\u03a5"+
|
||||||
|
"\u00c2\u0001\u0000\u0000\u0000\u03a6\u03a7\u0005&\u0000\u0000\u03a7\u03a8"+
|
||||||
|
"\u0005&\u0000\u0000\u03a8\u00c4\u0001\u0000\u0000\u0000\u03a9\u03aa\u0005"+
|
||||||
|
"|\u0000\u0000\u03aa\u03ab\u0005|\u0000\u0000\u03ab\u00c6\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03ac\u03ad\u0005+\u0000\u0000\u03ad\u03ae\u0005+\u0000\u0000\u03ae"+
|
||||||
|
"\u00c8\u0001\u0000\u0000\u0000\u03af\u03b0\u0005-\u0000\u0000\u03b0\u03b1"+
|
||||||
|
"\u0005-\u0000\u0000\u03b1\u00ca\u0001\u0000\u0000\u0000\u03b2\u03b3\u0005"+
|
||||||
|
"+\u0000\u0000\u03b3\u00cc\u0001\u0000\u0000\u0000\u03b4\u03b5\u0005-\u0000"+
|
||||||
|
"\u0000\u03b5\u00ce\u0001\u0000\u0000\u0000\u03b6\u03b7\u0005*\u0000\u0000"+
|
||||||
|
"\u03b7\u00d0\u0001\u0000\u0000\u0000\u03b8\u03b9\u0005/\u0000\u0000\u03b9"+
|
||||||
|
"\u00d2\u0001\u0000\u0000\u0000\u03ba\u03bb\u0005&\u0000\u0000\u03bb\u00d4"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u03bc\u03bd\u0005|\u0000\u0000\u03bd\u00d6\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u03be\u03bf\u0005^\u0000\u0000\u03bf\u00d8\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u03c0\u03c1\u0005%\u0000\u0000\u03c1\u00da\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03c2\u03c3\u0005+\u0000\u0000\u03c3\u03c4\u0005=\u0000\u0000\u03c4"+
|
||||||
|
"\u00dc\u0001\u0000\u0000\u0000\u03c5\u03c6\u0005-\u0000\u0000\u03c6\u03c7"+
|
||||||
|
"\u0005=\u0000\u0000\u03c7\u00de\u0001\u0000\u0000\u0000\u03c8\u03c9\u0005"+
|
||||||
|
"*\u0000\u0000\u03c9\u03ca\u0005=\u0000\u0000\u03ca\u00e0\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03cb\u03cc\u0005/\u0000\u0000\u03cc\u03cd\u0005=\u0000\u0000\u03cd"+
|
||||||
|
"\u00e2\u0001\u0000\u0000\u0000\u03ce\u03cf\u0005&\u0000\u0000\u03cf\u03d0"+
|
||||||
|
"\u0005=\u0000\u0000\u03d0\u00e4\u0001\u0000\u0000\u0000\u03d1\u03d2\u0005"+
|
||||||
|
"|\u0000\u0000\u03d2\u03d3\u0005=\u0000\u0000\u03d3\u00e6\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03d4\u03d5\u0005^\u0000\u0000\u03d5\u03d6\u0005=\u0000\u0000\u03d6"+
|
||||||
|
"\u00e8\u0001\u0000\u0000\u0000\u03d7\u03d8\u0005%\u0000\u0000\u03d8\u03d9"+
|
||||||
|
"\u0005=\u0000\u0000\u03d9\u00ea\u0001\u0000\u0000\u0000\u03da\u03db\u0005"+
|
||||||
|
"<\u0000\u0000\u03db\u03dc\u0005<\u0000\u0000\u03dc\u03dd\u0005=\u0000"+
|
||||||
|
"\u0000\u03dd\u00ec\u0001\u0000\u0000\u0000\u03de\u03df\u0005>\u0000\u0000"+
|
||||||
|
"\u03df\u03e0\u0005>\u0000\u0000\u03e0\u03e1\u0005=\u0000\u0000\u03e1\u00ee"+
|
||||||
|
"\u0001\u0000\u0000\u0000\u03e2\u03e3\u0005>\u0000\u0000\u03e3\u03e4\u0005"+
|
||||||
|
">\u0000\u0000\u03e4\u03e5\u0005>\u0000\u0000\u03e5\u03e6\u0005=\u0000"+
|
||||||
|
"\u0000\u03e6\u00f0\u0001\u0000\u0000\u0000\u03e7\u03e8\u0005-\u0000\u0000"+
|
||||||
|
"\u03e8\u03e9\u0005>\u0000\u0000\u03e9\u00f2\u0001\u0000\u0000\u0000\u03ea"+
|
||||||
|
"\u03eb\u0005:\u0000\u0000\u03eb\u03ec\u0005:\u0000\u0000\u03ec\u00f4\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u03ed\u03ee\u0005@\u0000\u0000\u03ee\u00f6\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u03ef\u03f0\u0005.\u0000\u0000\u03f0\u03f1\u0005.\u0000\u0000"+
|
||||||
|
"\u03f1\u03f2\u0005.\u0000\u0000\u03f2\u00f8\u0001\u0000\u0000\u0000\u03f3"+
|
||||||
|
"\u03f5\u0007\u0011\u0000\u0000\u03f4\u03f3\u0001\u0000\u0000\u0000\u03f5"+
|
||||||
|
"\u03f6\u0001\u0000\u0000\u0000\u03f6\u03f4\u0001\u0000\u0000\u0000\u03f6"+
|
||||||
|
"\u03f7\u0001\u0000\u0000\u0000\u03f7\u03f8\u0001\u0000\u0000\u0000\u03f8"+
|
||||||
|
"\u03f9\u0006|\u0000\u0000\u03f9\u00fa\u0001\u0000\u0000\u0000\u03fa\u03fb"+
|
||||||
|
"\u0005/\u0000\u0000\u03fb\u03fc\u0005*\u0000\u0000\u03fc\u0400\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u03fd\u03ff\t\u0000\u0000\u0000\u03fe\u03fd\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u03ff\u0402\u0001\u0000\u0000\u0000\u0400\u0401\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0400\u03fe\u0001\u0000\u0000\u0000\u0401\u0403\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0402\u0400\u0001\u0000\u0000\u0000\u0403\u0404\u0005*\u0000\u0000"+
|
||||||
|
"\u0404\u0405\u0005/\u0000\u0000\u0405\u0406\u0001\u0000\u0000\u0000\u0406"+
|
||||||
|
"\u0407\u0006}\u0000\u0000\u0407\u00fc\u0001\u0000\u0000\u0000\u0408\u0409"+
|
||||||
|
"\u0005/\u0000\u0000\u0409\u040a\u0005/\u0000\u0000\u040a\u040e\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u040b\u040d\b\u0010\u0000\u0000\u040c\u040b\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u040d\u0410\u0001\u0000\u0000\u0000\u040e\u040c\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u040e\u040f\u0001\u0000\u0000\u0000\u040f\u0411\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0410\u040e\u0001\u0000\u0000\u0000\u0411\u0412\u0006~\u0000\u0000"+
|
||||||
|
"\u0412\u00fe\u0001\u0000\u0000\u0000\u0413\u0417\u0003\u010d\u0086\u0000"+
|
||||||
|
"\u0414\u0416\u0003\u010b\u0085\u0000\u0415\u0414\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0416\u0419\u0001\u0000\u0000\u0000\u0417\u0415\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0417\u0418\u0001\u0000\u0000\u0000\u0418\u0100\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0419\u0417\u0001\u0000\u0000\u0000\u041a\u041c\u0007\u0012\u0000\u0000"+
|
||||||
|
"\u041b\u041d\u0007\f\u0000\u0000\u041c\u041b\u0001\u0000\u0000\u0000\u041c"+
|
||||||
|
"\u041d\u0001\u0000\u0000\u0000\u041d\u041e\u0001\u0000\u0000\u0000\u041e"+
|
||||||
|
"\u041f\u0003\u0109\u0084\u0000\u041f\u0102\u0001\u0000\u0000\u0000\u0420"+
|
||||||
|
"\u0421\u0005\\\u0000\u0000\u0421\u0436\u0007\u0013\u0000\u0000\u0422\u0427"+
|
||||||
|
"\u0005\\\u0000\u0000\u0423\u0425\u0007\u0014\u0000\u0000\u0424\u0423\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0424\u0425\u0001\u0000\u0000\u0000\u0425\u0426\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0426\u0428\u0007\u0005\u0000\u0000\u0427\u0424\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0427\u0428\u0001\u0000\u0000\u0000\u0428\u0429\u0001"+
|
||||||
|
"\u0000\u0000\u0000\u0429\u0436\u0007\u0005\u0000\u0000\u042a\u042c\u0005"+
|
||||||
|
"\\\u0000\u0000\u042b\u042d\u0005u\u0000\u0000\u042c\u042b\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u042d\u042e\u0001\u0000\u0000\u0000\u042e\u042c\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u042e\u042f\u0001\u0000\u0000\u0000\u042f\u0430\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0430\u0431\u0003\u0107\u0083\u0000\u0431\u0432\u0003\u0107"+
|
||||||
|
"\u0083\u0000\u0432\u0433\u0003\u0107\u0083\u0000\u0433\u0434\u0003\u0107"+
|
||||||
|
"\u0083\u0000\u0434\u0436\u0001\u0000\u0000\u0000\u0435\u0420\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0435\u0422\u0001\u0000\u0000\u0000\u0435\u042a\u0001\u0000"+
|
||||||
|
"\u0000\u0000\u0436\u0104\u0001\u0000\u0000\u0000\u0437\u0440\u0003\u0107"+
|
||||||
|
"\u0083\u0000\u0438\u043b\u0003\u0107\u0083\u0000\u0439\u043b\u0005_\u0000"+
|
||||||
|
"\u0000\u043a\u0438\u0001\u0000\u0000\u0000\u043a\u0439\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u043b\u043e\u0001\u0000\u0000\u0000\u043c\u043a\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u043c\u043d\u0001\u0000\u0000\u0000\u043d\u043f\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u043e\u043c\u0001\u0000\u0000\u0000\u043f\u0441\u0003\u0107\u0083"+
|
||||||
|
"\u0000\u0440\u043c\u0001\u0000\u0000\u0000\u0440\u0441\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0441\u0106\u0001\u0000\u0000\u0000\u0442\u0443\u0007\u0003\u0000"+
|
||||||
|
"\u0000\u0443\u0108\u0001\u0000\u0000\u0000\u0444\u044c\u0007\u0015\u0000"+
|
||||||
|
"\u0000\u0445\u0447\u0007\u0016\u0000\u0000\u0446\u0445\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0447\u044a\u0001\u0000\u0000\u0000\u0448\u0446\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0448\u0449\u0001\u0000\u0000\u0000\u0449\u044b\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u044a\u0448\u0001\u0000\u0000\u0000\u044b\u044d\u0007\u0015\u0000"+
|
||||||
|
"\u0000\u044c\u0448\u0001\u0000\u0000\u0000\u044c\u044d\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u044d\u010a\u0001\u0000\u0000\u0000\u044e\u0451\u0003\u010d\u0086"+
|
||||||
|
"\u0000\u044f\u0451\u0007\u0015\u0000\u0000\u0450\u044e\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0450\u044f\u0001\u0000\u0000\u0000\u0451\u010c\u0001\u0000\u0000"+
|
||||||
|
"\u0000\u0452\u0457\u0007\u0017\u0000\u0000\u0453\u0457\b\u0018\u0000\u0000"+
|
||||||
|
"\u0454\u0455\u0007\u0019\u0000\u0000\u0455\u0457\u0007\u001a\u0000\u0000"+
|
||||||
|
"\u0456\u0452\u0001\u0000\u0000\u0000\u0456\u0453\u0001\u0000\u0000\u0000"+
|
||||||
|
"\u0456\u0454\u0001\u0000\u0000\u0000\u0457\u010e\u0001\u0000\u0000\u0000"+
|
||||||
|
"3\u0000\u02d4\u02d9\u02dc\u02de\u02e1\u02e9\u02ed\u02f0\u02f6\u02fd\u0301"+
|
||||||
|
"\u0304\u030c\u0310\u0313\u0318\u031c\u031f\u0322\u0327\u032a\u032c\u0332"+
|
||||||
|
"\u0335\u0339\u033d\u0341\u034c\u0351\u0358\u035a\u0366\u036c\u036e\u03f6"+
|
||||||
|
"\u0400\u040e\u0417\u041c\u0424\u0427\u042e\u0435\u043a\u043c\u0440\u0448"+
|
||||||
|
"\u044c\u0450\u0456\u0001\u0000\u0001\u0000";
|
||||||
|
public static final ATN _ATN =
|
||||||
|
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||||
|
static {
|
||||||
|
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||||
|
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||||
|
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
242
gen/Java17Lexer.tokens
Normal file
242
gen/Java17Lexer.tokens
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
ABSTRACT=1
|
||||||
|
ASSERT=2
|
||||||
|
BOOLEAN=3
|
||||||
|
BREAK=4
|
||||||
|
BYTE=5
|
||||||
|
CASE=6
|
||||||
|
CATCH=7
|
||||||
|
CHAR=8
|
||||||
|
CLASS=9
|
||||||
|
CONST=10
|
||||||
|
CONTINUE=11
|
||||||
|
DEFAULT=12
|
||||||
|
DO=13
|
||||||
|
DOUBLE=14
|
||||||
|
ELSE=15
|
||||||
|
ENUM=16
|
||||||
|
EXTENDS=17
|
||||||
|
FINAL=18
|
||||||
|
FINALLY=19
|
||||||
|
FLOAT=20
|
||||||
|
FOR=21
|
||||||
|
IF=22
|
||||||
|
GOTO=23
|
||||||
|
IMPLEMENTS=24
|
||||||
|
IMPORT=25
|
||||||
|
INSTANCEOF=26
|
||||||
|
INT=27
|
||||||
|
INTERFACE=28
|
||||||
|
LONG=29
|
||||||
|
NATIVE=30
|
||||||
|
NEW=31
|
||||||
|
PACKAGE=32
|
||||||
|
PRIVATE=33
|
||||||
|
PROTECTED=34
|
||||||
|
PUBLIC=35
|
||||||
|
RETURN=36
|
||||||
|
SHORT=37
|
||||||
|
STATIC=38
|
||||||
|
STRICTFP=39
|
||||||
|
SUPER=40
|
||||||
|
SWITCH=41
|
||||||
|
SYNCHRONIZED=42
|
||||||
|
THIS=43
|
||||||
|
THROW=44
|
||||||
|
THROWS=45
|
||||||
|
TRANSIENT=46
|
||||||
|
TRY=47
|
||||||
|
VOID=48
|
||||||
|
VOLATILE=49
|
||||||
|
WHILE=50
|
||||||
|
MODULE=51
|
||||||
|
OPEN=52
|
||||||
|
REQUIRES=53
|
||||||
|
EXPORTS=54
|
||||||
|
OPENS=55
|
||||||
|
TO=56
|
||||||
|
USES=57
|
||||||
|
PROVIDES=58
|
||||||
|
WITH=59
|
||||||
|
TRANSITIVE=60
|
||||||
|
VAR=61
|
||||||
|
YIELD=62
|
||||||
|
RECORD=63
|
||||||
|
SEALED=64
|
||||||
|
PERMITS=65
|
||||||
|
NON_SEALED=66
|
||||||
|
DECIMAL_LITERAL=67
|
||||||
|
HEX_LITERAL=68
|
||||||
|
OCT_LITERAL=69
|
||||||
|
BINARY_LITERAL=70
|
||||||
|
FLOAT_LITERAL=71
|
||||||
|
HEX_FLOAT_LITERAL=72
|
||||||
|
BOOL_LITERAL=73
|
||||||
|
CHAR_LITERAL=74
|
||||||
|
STRING_LITERAL=75
|
||||||
|
TEXT_BLOCK=76
|
||||||
|
NULL_LITERAL=77
|
||||||
|
LPAREN=78
|
||||||
|
RPAREN=79
|
||||||
|
LBRACE=80
|
||||||
|
RBRACE=81
|
||||||
|
LBRACK=82
|
||||||
|
RBRACK=83
|
||||||
|
SEMI=84
|
||||||
|
COMMA=85
|
||||||
|
DOT=86
|
||||||
|
ASSIGN=87
|
||||||
|
GT=88
|
||||||
|
LT=89
|
||||||
|
BANG=90
|
||||||
|
TILDE=91
|
||||||
|
QUESTION=92
|
||||||
|
COLON=93
|
||||||
|
EQUAL=94
|
||||||
|
LE=95
|
||||||
|
GE=96
|
||||||
|
NOTEQUAL=97
|
||||||
|
AND=98
|
||||||
|
OR=99
|
||||||
|
INC=100
|
||||||
|
DEC=101
|
||||||
|
ADD=102
|
||||||
|
SUB=103
|
||||||
|
MUL=104
|
||||||
|
DIV=105
|
||||||
|
BITAND=106
|
||||||
|
BITOR=107
|
||||||
|
CARET=108
|
||||||
|
MOD=109
|
||||||
|
ADD_ASSIGN=110
|
||||||
|
SUB_ASSIGN=111
|
||||||
|
MUL_ASSIGN=112
|
||||||
|
DIV_ASSIGN=113
|
||||||
|
AND_ASSIGN=114
|
||||||
|
OR_ASSIGN=115
|
||||||
|
XOR_ASSIGN=116
|
||||||
|
MOD_ASSIGN=117
|
||||||
|
LSHIFT_ASSIGN=118
|
||||||
|
RSHIFT_ASSIGN=119
|
||||||
|
URSHIFT_ASSIGN=120
|
||||||
|
ARROW=121
|
||||||
|
COLONCOLON=122
|
||||||
|
AT=123
|
||||||
|
ELLIPSIS=124
|
||||||
|
WS=125
|
||||||
|
COMMENT=126
|
||||||
|
LINE_COMMENT=127
|
||||||
|
IDENTIFIER=128
|
||||||
|
'abstract'=1
|
||||||
|
'assert'=2
|
||||||
|
'boolean'=3
|
||||||
|
'break'=4
|
||||||
|
'byte'=5
|
||||||
|
'case'=6
|
||||||
|
'catch'=7
|
||||||
|
'char'=8
|
||||||
|
'class'=9
|
||||||
|
'const'=10
|
||||||
|
'continue'=11
|
||||||
|
'default'=12
|
||||||
|
'do'=13
|
||||||
|
'double'=14
|
||||||
|
'else'=15
|
||||||
|
'enum'=16
|
||||||
|
'extends'=17
|
||||||
|
'final'=18
|
||||||
|
'finally'=19
|
||||||
|
'float'=20
|
||||||
|
'for'=21
|
||||||
|
'if'=22
|
||||||
|
'goto'=23
|
||||||
|
'implements'=24
|
||||||
|
'import'=25
|
||||||
|
'instanceof'=26
|
||||||
|
'int'=27
|
||||||
|
'interface'=28
|
||||||
|
'long'=29
|
||||||
|
'native'=30
|
||||||
|
'new'=31
|
||||||
|
'package'=32
|
||||||
|
'private'=33
|
||||||
|
'protected'=34
|
||||||
|
'public'=35
|
||||||
|
'return'=36
|
||||||
|
'short'=37
|
||||||
|
'static'=38
|
||||||
|
'strictfp'=39
|
||||||
|
'super'=40
|
||||||
|
'switch'=41
|
||||||
|
'synchronized'=42
|
||||||
|
'this'=43
|
||||||
|
'throw'=44
|
||||||
|
'throws'=45
|
||||||
|
'transient'=46
|
||||||
|
'try'=47
|
||||||
|
'void'=48
|
||||||
|
'volatile'=49
|
||||||
|
'while'=50
|
||||||
|
'module'=51
|
||||||
|
'open'=52
|
||||||
|
'requires'=53
|
||||||
|
'exports'=54
|
||||||
|
'opens'=55
|
||||||
|
'to'=56
|
||||||
|
'uses'=57
|
||||||
|
'provides'=58
|
||||||
|
'with'=59
|
||||||
|
'transitive'=60
|
||||||
|
'var'=61
|
||||||
|
'yield'=62
|
||||||
|
'record'=63
|
||||||
|
'sealed'=64
|
||||||
|
'permits'=65
|
||||||
|
'non-sealed'=66
|
||||||
|
'null'=77
|
||||||
|
'('=78
|
||||||
|
')'=79
|
||||||
|
'{'=80
|
||||||
|
'}'=81
|
||||||
|
'['=82
|
||||||
|
']'=83
|
||||||
|
';'=84
|
||||||
|
','=85
|
||||||
|
'.'=86
|
||||||
|
'='=87
|
||||||
|
'>'=88
|
||||||
|
'<'=89
|
||||||
|
'!'=90
|
||||||
|
'~'=91
|
||||||
|
'?'=92
|
||||||
|
':'=93
|
||||||
|
'=='=94
|
||||||
|
'<='=95
|
||||||
|
'>='=96
|
||||||
|
'!='=97
|
||||||
|
'&&'=98
|
||||||
|
'||'=99
|
||||||
|
'++'=100
|
||||||
|
'--'=101
|
||||||
|
'+'=102
|
||||||
|
'-'=103
|
||||||
|
'*'=104
|
||||||
|
'/'=105
|
||||||
|
'&'=106
|
||||||
|
'|'=107
|
||||||
|
'^'=108
|
||||||
|
'%'=109
|
||||||
|
'+='=110
|
||||||
|
'-='=111
|
||||||
|
'*='=112
|
||||||
|
'/='=113
|
||||||
|
'&='=114
|
||||||
|
'|='=115
|
||||||
|
'^='=116
|
||||||
|
'%='=117
|
||||||
|
'<<='=118
|
||||||
|
'>>='=119
|
||||||
|
'>>>='=120
|
||||||
|
'->'=121
|
||||||
|
'::'=122
|
||||||
|
'@'=123
|
||||||
|
'...'=124
|
406
gen/Java17Parser.interp
Normal file
406
gen/Java17Parser.interp
Normal file
File diff suppressed because one or more lines are too long
15685
gen/Java17Parser.java
Normal file
15685
gen/Java17Parser.java
Normal file
File diff suppressed because it is too large
Load Diff
242
gen/Java17Parser.tokens
Normal file
242
gen/Java17Parser.tokens
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
ABSTRACT=1
|
||||||
|
ASSERT=2
|
||||||
|
BOOLEAN=3
|
||||||
|
BREAK=4
|
||||||
|
BYTE=5
|
||||||
|
CASE=6
|
||||||
|
CATCH=7
|
||||||
|
CHAR=8
|
||||||
|
CLASS=9
|
||||||
|
CONST=10
|
||||||
|
CONTINUE=11
|
||||||
|
DEFAULT=12
|
||||||
|
DO=13
|
||||||
|
DOUBLE=14
|
||||||
|
ELSE=15
|
||||||
|
ENUM=16
|
||||||
|
EXTENDS=17
|
||||||
|
FINAL=18
|
||||||
|
FINALLY=19
|
||||||
|
FLOAT=20
|
||||||
|
FOR=21
|
||||||
|
IF=22
|
||||||
|
GOTO=23
|
||||||
|
IMPLEMENTS=24
|
||||||
|
IMPORT=25
|
||||||
|
INSTANCEOF=26
|
||||||
|
INT=27
|
||||||
|
INTERFACE=28
|
||||||
|
LONG=29
|
||||||
|
NATIVE=30
|
||||||
|
NEW=31
|
||||||
|
PACKAGE=32
|
||||||
|
PRIVATE=33
|
||||||
|
PROTECTED=34
|
||||||
|
PUBLIC=35
|
||||||
|
RETURN=36
|
||||||
|
SHORT=37
|
||||||
|
STATIC=38
|
||||||
|
STRICTFP=39
|
||||||
|
SUPER=40
|
||||||
|
SWITCH=41
|
||||||
|
SYNCHRONIZED=42
|
||||||
|
THIS=43
|
||||||
|
THROW=44
|
||||||
|
THROWS=45
|
||||||
|
TRANSIENT=46
|
||||||
|
TRY=47
|
||||||
|
VOID=48
|
||||||
|
VOLATILE=49
|
||||||
|
WHILE=50
|
||||||
|
MODULE=51
|
||||||
|
OPEN=52
|
||||||
|
REQUIRES=53
|
||||||
|
EXPORTS=54
|
||||||
|
OPENS=55
|
||||||
|
TO=56
|
||||||
|
USES=57
|
||||||
|
PROVIDES=58
|
||||||
|
WITH=59
|
||||||
|
TRANSITIVE=60
|
||||||
|
VAR=61
|
||||||
|
YIELD=62
|
||||||
|
RECORD=63
|
||||||
|
SEALED=64
|
||||||
|
PERMITS=65
|
||||||
|
NON_SEALED=66
|
||||||
|
DECIMAL_LITERAL=67
|
||||||
|
HEX_LITERAL=68
|
||||||
|
OCT_LITERAL=69
|
||||||
|
BINARY_LITERAL=70
|
||||||
|
FLOAT_LITERAL=71
|
||||||
|
HEX_FLOAT_LITERAL=72
|
||||||
|
BOOL_LITERAL=73
|
||||||
|
CHAR_LITERAL=74
|
||||||
|
STRING_LITERAL=75
|
||||||
|
TEXT_BLOCK=76
|
||||||
|
NULL_LITERAL=77
|
||||||
|
LPAREN=78
|
||||||
|
RPAREN=79
|
||||||
|
LBRACE=80
|
||||||
|
RBRACE=81
|
||||||
|
LBRACK=82
|
||||||
|
RBRACK=83
|
||||||
|
SEMI=84
|
||||||
|
COMMA=85
|
||||||
|
DOT=86
|
||||||
|
ASSIGN=87
|
||||||
|
GT=88
|
||||||
|
LT=89
|
||||||
|
BANG=90
|
||||||
|
TILDE=91
|
||||||
|
QUESTION=92
|
||||||
|
COLON=93
|
||||||
|
EQUAL=94
|
||||||
|
LE=95
|
||||||
|
GE=96
|
||||||
|
NOTEQUAL=97
|
||||||
|
AND=98
|
||||||
|
OR=99
|
||||||
|
INC=100
|
||||||
|
DEC=101
|
||||||
|
ADD=102
|
||||||
|
SUB=103
|
||||||
|
MUL=104
|
||||||
|
DIV=105
|
||||||
|
BITAND=106
|
||||||
|
BITOR=107
|
||||||
|
CARET=108
|
||||||
|
MOD=109
|
||||||
|
ADD_ASSIGN=110
|
||||||
|
SUB_ASSIGN=111
|
||||||
|
MUL_ASSIGN=112
|
||||||
|
DIV_ASSIGN=113
|
||||||
|
AND_ASSIGN=114
|
||||||
|
OR_ASSIGN=115
|
||||||
|
XOR_ASSIGN=116
|
||||||
|
MOD_ASSIGN=117
|
||||||
|
LSHIFT_ASSIGN=118
|
||||||
|
RSHIFT_ASSIGN=119
|
||||||
|
URSHIFT_ASSIGN=120
|
||||||
|
ARROW=121
|
||||||
|
COLONCOLON=122
|
||||||
|
AT=123
|
||||||
|
ELLIPSIS=124
|
||||||
|
WS=125
|
||||||
|
COMMENT=126
|
||||||
|
LINE_COMMENT=127
|
||||||
|
IDENTIFIER=128
|
||||||
|
'abstract'=1
|
||||||
|
'assert'=2
|
||||||
|
'boolean'=3
|
||||||
|
'break'=4
|
||||||
|
'byte'=5
|
||||||
|
'case'=6
|
||||||
|
'catch'=7
|
||||||
|
'char'=8
|
||||||
|
'class'=9
|
||||||
|
'const'=10
|
||||||
|
'continue'=11
|
||||||
|
'default'=12
|
||||||
|
'do'=13
|
||||||
|
'double'=14
|
||||||
|
'else'=15
|
||||||
|
'enum'=16
|
||||||
|
'extends'=17
|
||||||
|
'final'=18
|
||||||
|
'finally'=19
|
||||||
|
'float'=20
|
||||||
|
'for'=21
|
||||||
|
'if'=22
|
||||||
|
'goto'=23
|
||||||
|
'implements'=24
|
||||||
|
'import'=25
|
||||||
|
'instanceof'=26
|
||||||
|
'int'=27
|
||||||
|
'interface'=28
|
||||||
|
'long'=29
|
||||||
|
'native'=30
|
||||||
|
'new'=31
|
||||||
|
'package'=32
|
||||||
|
'private'=33
|
||||||
|
'protected'=34
|
||||||
|
'public'=35
|
||||||
|
'return'=36
|
||||||
|
'short'=37
|
||||||
|
'static'=38
|
||||||
|
'strictfp'=39
|
||||||
|
'super'=40
|
||||||
|
'switch'=41
|
||||||
|
'synchronized'=42
|
||||||
|
'this'=43
|
||||||
|
'throw'=44
|
||||||
|
'throws'=45
|
||||||
|
'transient'=46
|
||||||
|
'try'=47
|
||||||
|
'void'=48
|
||||||
|
'volatile'=49
|
||||||
|
'while'=50
|
||||||
|
'module'=51
|
||||||
|
'open'=52
|
||||||
|
'requires'=53
|
||||||
|
'exports'=54
|
||||||
|
'opens'=55
|
||||||
|
'to'=56
|
||||||
|
'uses'=57
|
||||||
|
'provides'=58
|
||||||
|
'with'=59
|
||||||
|
'transitive'=60
|
||||||
|
'var'=61
|
||||||
|
'yield'=62
|
||||||
|
'record'=63
|
||||||
|
'sealed'=64
|
||||||
|
'permits'=65
|
||||||
|
'non-sealed'=66
|
||||||
|
'null'=77
|
||||||
|
'('=78
|
||||||
|
')'=79
|
||||||
|
'{'=80
|
||||||
|
'}'=81
|
||||||
|
'['=82
|
||||||
|
']'=83
|
||||||
|
';'=84
|
||||||
|
','=85
|
||||||
|
'.'=86
|
||||||
|
'='=87
|
||||||
|
'>'=88
|
||||||
|
'<'=89
|
||||||
|
'!'=90
|
||||||
|
'~'=91
|
||||||
|
'?'=92
|
||||||
|
':'=93
|
||||||
|
'=='=94
|
||||||
|
'<='=95
|
||||||
|
'>='=96
|
||||||
|
'!='=97
|
||||||
|
'&&'=98
|
||||||
|
'||'=99
|
||||||
|
'++'=100
|
||||||
|
'--'=101
|
||||||
|
'+'=102
|
||||||
|
'-'=103
|
||||||
|
'*'=104
|
||||||
|
'/'=105
|
||||||
|
'&'=106
|
||||||
|
'|'=107
|
||||||
|
'^'=108
|
||||||
|
'%'=109
|
||||||
|
'+='=110
|
||||||
|
'-='=111
|
||||||
|
'*='=112
|
||||||
|
'/='=113
|
||||||
|
'&='=114
|
||||||
|
'|='=115
|
||||||
|
'^='=116
|
||||||
|
'%='=117
|
||||||
|
'<<='=118
|
||||||
|
'>>='=119
|
||||||
|
'>>>='=120
|
||||||
|
'->'=121
|
||||||
|
'::'=122
|
||||||
|
'@'=123
|
||||||
|
'...'=124
|
2667
gen/Java17ParserBaseListener.java
Normal file
2667
gen/Java17ParserBaseListener.java
Normal file
File diff suppressed because it is too large
Load Diff
1547
gen/Java17ParserBaseVisitor.java
Normal file
1547
gen/Java17ParserBaseVisitor.java
Normal file
File diff suppressed because it is too large
Load Diff
2397
gen/Java17ParserListener.java
Normal file
2397
gen/Java17ParserListener.java
Normal file
File diff suppressed because it is too large
Load Diff
1425
gen/Java17ParserVisitor.java
Normal file
1425
gen/Java17ParserVisitor.java
Normal file
File diff suppressed because it is too large
Load Diff
57
pom.xml
57
pom.xml
@@ -12,60 +12,79 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
<version>4.11</version>
|
<version>5.13.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4</artifactId>
|
<artifactId>antlr4</artifactId>
|
||||||
<version>4.11.1</version>
|
<version>4.13.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.6</version>
|
<version>2.19.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.classgraph</groupId>
|
||||||
|
<artifactId>classgraph</artifactId>
|
||||||
|
<version>4.8.180</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>22.0</version>
|
<version>33.4.8-jre</version>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.reflections</groupId>
|
|
||||||
<artifactId>reflections</artifactId>
|
|
||||||
<version>0.9.11</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>asm</artifactId>
|
<artifactId>asm</artifactId>
|
||||||
<version>9.5</version>
|
<version>9.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>0.8.13</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.11.0</version>
|
<version>3.14.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>21</source>
|
<source>23</source>
|
||||||
<target>21</target>
|
<target>23</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.5.3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||||
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
||||||
<argLine>--enable-preview</argLine>
|
<argLine>${argLine} --enable-preview</argLine>
|
||||||
<trimStackTrace>false</trimStackTrace>
|
<trimStackTrace>false</trimStackTrace>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/JavaTXCompilerTest.java</exclude>
|
<exclude>**/JavaTXCompilerTest.java</exclude>
|
||||||
@@ -77,7 +96,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
<version>4.11.1</version>
|
<version>4.13.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>antlr</id>
|
<id>antlr</id>
|
||||||
@@ -90,7 +109,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.4.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
|
10
resources/AllgemeinTest/Bar.java
Normal file
10
resources/AllgemeinTest/Bar.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
public class Bar{
|
||||||
|
|
||||||
|
void visit(Object o){
|
||||||
|
System.out.println("Object");
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(Bla f){
|
||||||
|
System.out.println("Foo");
|
||||||
|
}
|
||||||
|
}
|
@@ -1,10 +1,12 @@
|
|||||||
class Box<A> {
|
public class Box {
|
||||||
|
|
||||||
A a;
|
a;
|
||||||
|
|
||||||
Box(A a) {
|
public Box() { }
|
||||||
this.a = a;
|
public Box(a) {
|
||||||
|
//this.a = a;
|
||||||
}
|
}
|
||||||
}
|
set(x) {
|
||||||
|
a = x;
|
||||||
|
}
|
||||||
|
}
|
6
resources/AllgemeinTest/Foo.jav
Normal file
6
resources/AllgemeinTest/Foo.jav
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
public class Foo{
|
||||||
|
|
||||||
|
public accept(Bar b){
|
||||||
|
b.visit(this);
|
||||||
|
}
|
||||||
|
}
|
15
resources/bytecode/javFiles/Assign.jav
Normal file
15
resources/bytecode/javFiles/Assign.jav
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class Assign {
|
||||||
|
public x = 10;
|
||||||
|
public y = this;
|
||||||
|
|
||||||
|
public call() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public m() {
|
||||||
|
this.call().call().y.x = 20;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,9 @@
|
|||||||
class B { }
|
public class Box<A> {
|
||||||
class Box_Main extends B {
|
|
||||||
m(b) {
|
A a;
|
||||||
b.m(new Box_Main());
|
|
||||||
b.m(new B());
|
public Box() { }
|
||||||
}
|
public Box(A a) {
|
||||||
}
|
//this.a = a;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +0,0 @@
|
|||||||
class Box<A> {
|
|
||||||
void m(A a) { }
|
|
||||||
}
|
|
@@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class Bug325 {
|
public class Bug325 {
|
||||||
public main() {
|
public main() {
|
||||||
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
|
var list = new ArrayList<>(List.of(1,2,3,4,5));
|
||||||
var func = x -> x*2;
|
var func = x -> x*2;
|
||||||
return list.stream().map(func).toList();
|
return list.stream().map(func).toList();
|
||||||
}
|
}
|
||||||
|
15
resources/bytecode/javFiles/Bug332.jav
Normal file
15
resources/bytecode/javFiles/Bug332.jav
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
|
interface Visitor {
|
||||||
|
public void visit(Object obj);
|
||||||
|
public void visit(ClassA a);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassA {
|
||||||
|
void accept(Visitor v) {
|
||||||
|
v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Bug332 {
|
||||||
|
}
|
11
resources/bytecode/javFiles/Bug333.jav
Normal file
11
resources/bytecode/javFiles/Bug333.jav
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public class Bug333 {
|
||||||
|
public static String Bar = "Bar";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar {
|
||||||
|
public bar() {
|
||||||
|
String s = Bug333.Bar;
|
||||||
|
}
|
||||||
|
}
|
10
resources/bytecode/javFiles/Bug337.jav
Normal file
10
resources/bytecode/javFiles/Bug337.jav
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Number;
|
||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
|
public class Bug337 {
|
||||||
|
public void main() {
|
||||||
|
Fun1$$<Object, Integer> fun1 = x -> x.hashCode() + 1;
|
||||||
|
Fun1$$<Number, Number> fun2 = fun1;
|
||||||
|
}
|
||||||
|
}
|
11
resources/bytecode/javFiles/Bug338.jav
Normal file
11
resources/bytecode/javFiles/Bug338.jav
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import java.util.List;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Bug338 {
|
||||||
|
public hashCode() {
|
||||||
|
return List.of(42);
|
||||||
|
}
|
||||||
|
}
|
2
resources/bytecode/javFiles/Bug343.jav
Normal file
2
resources/bytecode/javFiles/Bug343.jav
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
public record Bug343() {
|
||||||
|
}
|
22
resources/bytecode/javFiles/Bug363.jav
Normal file
22
resources/bytecode/javFiles/Bug363.jav
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
|
||||||
|
public class Bug363 {
|
||||||
|
uncurry (f){
|
||||||
|
return x -> f.apply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
uncurry (f){
|
||||||
|
return (x, y) -> f.apply(x).apply(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
uncurry (f){
|
||||||
|
return (x, y, z) -> f.apply(x).apply(y).apply(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public test(){
|
||||||
|
var f = x -> y -> z -> x + y + z;
|
||||||
|
var g = uncurry(f);
|
||||||
|
return g.apply("A", "B", "C"); // Outputs: 6
|
||||||
|
}
|
||||||
|
}
|
8
resources/bytecode/javFiles/Bug364.jav
Normal file
8
resources/bytecode/javFiles/Bug364.jav
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public class Bug364{
|
||||||
|
public main(){
|
||||||
|
var f = x -> y -> z -> x + y + z;
|
||||||
|
return f.apply("A").apply("B").apply("C");
|
||||||
|
}
|
||||||
|
}
|
21
resources/bytecode/javFiles/Bug365.jav
Normal file
21
resources/bytecode/javFiles/Bug365.jav
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
|
public class Bug365{
|
||||||
|
swap(f){
|
||||||
|
return x -> y -> f.apply(y).apply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(Fun1$$<String, Fun1$$<String, Fun1$$<String, Object>>> f){
|
||||||
|
return x -> y -> z -> f.apply(z).apply(y).apply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ex1() {
|
||||||
|
var func = x -> y -> z -> x + y + z;
|
||||||
|
return func.apply("A").apply("B").apply("C");
|
||||||
|
}
|
||||||
|
public ex2() {
|
||||||
|
var func = x -> y -> z -> x + y + z;
|
||||||
|
return swap(func).apply("A").apply("B").apply("C");
|
||||||
|
}
|
||||||
|
}
|
12
resources/bytecode/javFiles/Bug366.jav
Normal file
12
resources/bytecode/javFiles/Bug366.jav
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class Bug366 {
|
||||||
|
public static lambda() {
|
||||||
|
return (a, b) -> a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static test() {
|
||||||
|
var l = lambda();
|
||||||
|
return l.apply(10, 20);
|
||||||
|
}
|
||||||
|
}
|
10
resources/bytecode/javFiles/Bug371.jav
Normal file
10
resources/bytecode/javFiles/Bug371.jav
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
public class Bug371 {
|
||||||
|
static m1(x, y) { return x || y; }
|
||||||
|
static m2(x, y) { return x && y; }
|
||||||
|
|
||||||
|
public static test() {
|
||||||
|
return m2(m1(true, false), true);
|
||||||
|
}
|
||||||
|
}
|
17
resources/bytecode/javFiles/Bug373.jav
Normal file
17
resources/bytecode/javFiles/Bug373.jav
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import java.lang.Boolean;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.Character;
|
||||||
|
|
||||||
|
public class Bug373 {
|
||||||
|
public static main() {
|
||||||
|
System.out.println(true);
|
||||||
|
System.out.println(false);
|
||||||
|
System.out.println(1);
|
||||||
|
System.out.println(1l);
|
||||||
|
System.out.println(1.0);
|
||||||
|
System.out.println(1.0f);
|
||||||
|
System.out.println('a');
|
||||||
|
}
|
||||||
|
}
|
@@ -1,16 +0,0 @@
|
|||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
class BugXXX {
|
|
||||||
public main() {
|
|
||||||
List<Integer> i = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9,10));
|
|
||||||
Optional<Integer> tmp = i.stream().filter(x -> x == 5).map(x -> x*2).findFirst();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
}
|
|
1
resources/bytecode/javFiles/GenericRecord.jav
Normal file
1
resources/bytecode/javFiles/GenericRecord.jav
Normal file
@@ -0,0 +1 @@
|
|||||||
|
public record GenericRecord<T>(T a) {}
|
24
resources/bytecode/javFiles/GenericRecordSwitchCase.jav
Normal file
24
resources/bytecode/javFiles/GenericRecordSwitchCase.jav
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
sealed interface List permits LinkedElem, Elem {}
|
||||||
|
|
||||||
|
|
||||||
|
public record LinkedElem<T>(T a,List l) implements List{}
|
||||||
|
public record Elem<T>(T c) implements List{}
|
||||||
|
|
||||||
|
public class GenericRecordSwitchCase {
|
||||||
|
public main(o) {
|
||||||
|
return switch(o) {
|
||||||
|
case LinkedElem(a, Elem(e)) -> a ;
|
||||||
|
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
5
resources/bytecode/javFiles/ImportWildcard.jav
Normal file
5
resources/bytecode/javFiles/ImportWildcard.jav
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import java.lang.*;
|
||||||
|
|
||||||
|
public class ImportWildcard {
|
||||||
|
m(a, b) { return a * b; }
|
||||||
|
}
|
@@ -1,16 +0,0 @@
|
|||||||
import java.lang.Runnable;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
public class LamRunnable {
|
|
||||||
|
|
||||||
public LamRunnable() {
|
|
||||||
Runnable lam = () -> {
|
|
||||||
System.out.println("lambda");
|
|
||||||
};
|
|
||||||
|
|
||||||
lam.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
14
resources/bytecode/javFiles/Main.jav
Normal file
14
resources/bytecode/javFiles/Main.jav
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.lang.Iterable;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
class Main {
|
||||||
|
static main(args) {
|
||||||
|
for (var arg : args) {
|
||||||
|
System.out.println(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
resources/bytecode/javFiles/OverloadNestedPattern.jav
Normal file
20
resources/bytecode/javFiles/OverloadNestedPattern.jav
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Float;
|
||||||
|
|
||||||
|
public record R(Object nested) {}
|
||||||
|
|
||||||
|
public class OverloadNestedPattern {
|
||||||
|
|
||||||
|
public Integer m(R(R(Integer a)), R(Integer b)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer m(R(R(Float a)), R(Float b)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer m(R(Integer a), R(Integer b)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,15 +2,31 @@ import java.lang.Integer;
|
|||||||
import java.lang.Number;
|
import java.lang.Number;
|
||||||
import java.lang.Float;
|
import java.lang.Float;
|
||||||
|
|
||||||
record Point(Number x, Number y) {}
|
public record Point(Number x, Number y) {}
|
||||||
|
|
||||||
public class OverloadPattern {
|
public class OverloadPattern {
|
||||||
public m(Point(Integer x, Integer y)) {
|
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
|
||||||
return x + y;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public m(Point(Float x, Float y)) {
|
public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) {
|
||||||
return x * y;
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number m(Point(Float x, Float y), Point(Integer a, Integer b)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number m(Point(Float x, Float y), Point(Float a, Float b)) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number m(Point(Integer x, Integer y)) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number m(Point(Float x, Float y)) {
|
||||||
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
public m(Integer x) {
|
public m(Integer x) {
|
||||||
|
21
resources/bytecode/javFiles/PatternMatchingHaskellStyle.jav
Normal file
21
resources/bytecode/javFiles/PatternMatchingHaskellStyle.jav
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
sealed interface List<T> permits LinkedElem, Elem {}
|
||||||
|
|
||||||
|
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
|
||||||
|
public record Elem<T>(T a) implements List<T> {}
|
||||||
|
|
||||||
|
public class PatternMatchingHaskellStyle {
|
||||||
|
|
||||||
|
public append(LinkedElem(a, b), list2) {
|
||||||
|
return handleAppend(a, b, list2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleAppend(a, Elem(e), list2) {
|
||||||
|
return new LinkedElem<>(a, new LinkedElem<>(e, list2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleAppend(a, LinkedElem(e,r), list2) {
|
||||||
|
return new LinkedElem<>(a, append(new LinkedElem(e, r), list2));
|
||||||
|
}
|
||||||
|
}
|
26
resources/bytecode/javFiles/PatternMatchingListAppend.jav
Normal file
26
resources/bytecode/javFiles/PatternMatchingListAppend.jav
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import java.lang.Boolean;
|
||||||
|
import java.lang.Object;
|
||||||
|
|
||||||
|
sealed interface List<T> permits Cons, Empty {}
|
||||||
|
|
||||||
|
public record Cons<T>(T a, List<T> l) implements List<T> {}
|
||||||
|
public record Empty<T>() implements List<T> {}
|
||||||
|
|
||||||
|
public class PatternMatchingListAppend {
|
||||||
|
|
||||||
|
public append(Cons(a, b), list2) {
|
||||||
|
return new Cons<>(a, append(b, list2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public append(Empty(), list2) {
|
||||||
|
return list2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public append(a, list2) {
|
||||||
|
switch(a) {
|
||||||
|
case Cons(x, y) -> ...
|
||||||
|
case Empty() ->
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
17
resources/bytecode/javFiles/PatternMatchingLiteralStyle.jav
Normal file
17
resources/bytecode/javFiles/PatternMatchingLiteralStyle.jav
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Double;
|
||||||
|
import java.lang.Number;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public record R(Number n) {}
|
||||||
|
|
||||||
|
public class SwitchOverload {
|
||||||
|
|
||||||
|
public f(){}
|
||||||
|
|
||||||
|
public m(r) {
|
||||||
|
return switch(r) {
|
||||||
|
case R("test") -> f();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -11,7 +11,7 @@ public class Switch {
|
|||||||
case Rec(Integer a, Float b) -> a + 10;
|
case Rec(Integer a, Float b) -> a + 10;
|
||||||
case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c;
|
case Rec(Integer a, Rec(Integer b, Integer c)) -> a + b + c;
|
||||||
case Integer i -> i;
|
case Integer i -> i;
|
||||||
default -> 0;
|
//default -> 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
16
resources/bytecode/javFiles/SwitchAppend.jav
Normal file
16
resources/bytecode/javFiles/SwitchAppend.jav
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
sealed interface List<T> permits LinkedElem, Elem {}
|
||||||
|
|
||||||
|
public record LinkedElem<T>(T a, List<T> l) implements List<T> {}
|
||||||
|
public record Elem<T>(T a) implements List<T> {}
|
||||||
|
|
||||||
|
public class SwitchAppend {
|
||||||
|
public append(l1, l2) {
|
||||||
|
return switch(l1) {
|
||||||
|
case LinkedElem(a, Elem(e)) -> new LinkedElem<>(a, new LinkedElem<>(e, l2));
|
||||||
|
case LinkedElem(a, r) -> new LinkedElem<>(a, append(r, l2));
|
||||||
|
//Alternativ:
|
||||||
|
//case LinkedElem(a, LinkedElem(e, r)) -> new LinkedElem<>(a, append(new LinkedElem(e, r), l2));
|
||||||
|
//default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
22
resources/bytecode/javFiles/SwitchCaseHeritageDetection.jav
Normal file
22
resources/bytecode/javFiles/SwitchCaseHeritageDetection.jav
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public class NumberOrText{}
|
||||||
|
public class Text extends NumberOrText{};
|
||||||
|
public class Number extends NumberOrText{};
|
||||||
|
|
||||||
|
|
||||||
|
public record Cons(Integer a, NumberOrText l){}
|
||||||
|
|
||||||
|
|
||||||
|
public class SwitchCaseHeritageDetection {
|
||||||
|
public main(o) {
|
||||||
|
return switch(o) {
|
||||||
|
case Cons(a, Text b) -> "Second Element is a Text";
|
||||||
|
case Cons(a, Number b) -> "Second Element is a Number";
|
||||||
|
default -> "None of the above cases";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
17
resources/bytecode/javFiles/SwitchInfered.jav
Normal file
17
resources/bytecode/javFiles/SwitchInfered.jav
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public record Rec(Object a, Object b) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class SwitchInfered {
|
||||||
|
public main(o) {
|
||||||
|
return switch (o) {
|
||||||
|
case Rec(a, b) -> "asd";
|
||||||
|
default -> "cde";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
14
resources/bytecode/javFiles/SwitchNestedValue.jav
Normal file
14
resources/bytecode/javFiles/SwitchNestedValue.jav
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public record R(Integer i) {}
|
||||||
|
|
||||||
|
public class SwitchNestedValue {
|
||||||
|
public main(r) {
|
||||||
|
return switch(r) {
|
||||||
|
case R(10) -> 1;
|
||||||
|
case R(20) -> 2;
|
||||||
|
case R(i) -> 3;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
21
resources/bytecode/javFiles/SwitchOverload.jav
Normal file
21
resources/bytecode/javFiles/SwitchOverload.jav
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Double;
|
||||||
|
import java.lang.Number;
|
||||||
|
|
||||||
|
public record R(Number n) {}
|
||||||
|
|
||||||
|
public class SwitchOverload {
|
||||||
|
|
||||||
|
Number f(Double d) { return d * 2; }
|
||||||
|
Number f(Integer i) { return i * 5; }
|
||||||
|
|
||||||
|
public m(r, x) {
|
||||||
|
x = x + x;
|
||||||
|
return switch(r) {
|
||||||
|
case R(o) -> {
|
||||||
|
x = x + x;
|
||||||
|
yield f(o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
27
resources/bytecode/javFiles/SwitchRecordList.jav
Normal file
27
resources/bytecode/javFiles/SwitchRecordList.jav
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
sealed interface List permits LinkedElem, Elem {}
|
||||||
|
|
||||||
|
|
||||||
|
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet
|
||||||
|
public record Elem(Integer c) implements List{} //Implementiert List, wird aber nicht permittet
|
||||||
|
|
||||||
|
public class SwitchCaseHeritageDetection {
|
||||||
|
public main(o) {
|
||||||
|
return switch(o) {
|
||||||
|
case LinkedElem(a, Elem(e)) -> a + e;
|
||||||
|
case LinkedElem(a, LinkedElem(e, Elem(f))) -> a + e + f;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -9,4 +9,13 @@ public class While {
|
|||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public m2() {
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
} while(i < 10);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -2,41 +2,21 @@ import java.lang.Integer;
|
|||||||
|
|
||||||
public class Y {
|
public class Y {
|
||||||
y;
|
y;
|
||||||
//factorial;
|
|
||||||
|
|
||||||
public Y() {
|
public Y() {
|
||||||
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
||||||
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
getY() {
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
class fac1 {
|
|
||||||
factorial;
|
|
||||||
|
|
||||||
fac1() {
|
|
||||||
var y;
|
|
||||||
y = new Y<Integer,Integer,Integer,Integer,Integer>().getY();
|
|
||||||
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ergibt Parse-Error
|
public class Fac1 {
|
||||||
class fac1 {
|
public factorial;
|
||||||
factorial;
|
public Fac1() {
|
||||||
|
|
||||||
fac1() {
|
|
||||||
var y;
|
var y;
|
||||||
y = new Y<>().y;
|
var tmp = new Y<>(); // TODO Having new Y<>().y on one line doesn't work, see FIXME in StatementGenerator
|
||||||
|
y = tmp.y;
|
||||||
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
||||||
}
|
}
|
||||||
public static void main(String args[]) {
|
|
||||||
System.out.println(new fac1().factorial.apply(3));
|
public fac(v) {
|
||||||
|
return factorial.apply(v);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
*/
|
|
@@ -654,14 +654,17 @@ primaryPattern
|
|||||||
: typePattern #tPattern
|
: typePattern #tPattern
|
||||||
| recordPattern #rPattern
|
| recordPattern #rPattern
|
||||||
| '(' pattern ')' #enclosedPattern
|
| '(' pattern ')' #enclosedPattern
|
||||||
|
| literal (',' literal)* #lPattern
|
||||||
;
|
;
|
||||||
|
|
||||||
recordPattern
|
recordPattern
|
||||||
: typeType recordStructurePattern identifier?
|
: typeType recordStructurePattern identifier?
|
||||||
|
//| recordStructurePattern identifier?
|
||||||
;
|
;
|
||||||
|
|
||||||
typePattern
|
typePattern
|
||||||
: variableModifier* typeType identifier
|
: variableModifier* typeType identifier
|
||||||
|
| variableModifier* identifier
|
||||||
;
|
;
|
||||||
|
|
||||||
recordStructurePattern
|
recordStructurePattern
|
||||||
@@ -717,10 +720,10 @@ switchLabeledRule
|
|||||||
;
|
;
|
||||||
|
|
||||||
switchLabelCase
|
switchLabelCase
|
||||||
: CASE expressionList (ARROW | COLON) #labeledRuleExprList
|
: CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
|
||||||
| CASE NULL_LITERAL (ARROW | COLON) #labeledRuleNull
|
|
||||||
| CASE pattern (ARROW | COLON) #labeledRulePattern
|
| CASE pattern (ARROW | COLON) #labeledRulePattern
|
||||||
| DEFAULT (ARROW | COLON) #labeledRuleDefault
|
| DEFAULT (ARROW | COLON) #labeledRuleDefault
|
||||||
|
| CASE expressionList (ARROW | COLON) #labeledRuleExprList
|
||||||
;
|
;
|
||||||
|
|
||||||
// Java20
|
// Java20
|
||||||
|
@@ -2,12 +2,9 @@ package de.dhbwstuttgart.bytecode;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
|
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
@@ -16,7 +13,7 @@ import org.objectweb.asm.*;
|
|||||||
import java.lang.invoke.*;
|
import java.lang.invoke.*;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||||
@@ -31,15 +28,21 @@ public class Codegen {
|
|||||||
private final JavaTXCompiler compiler;
|
private final JavaTXCompiler compiler;
|
||||||
private final ASTToTargetAST converter;
|
private final ASTToTargetAST converter;
|
||||||
|
|
||||||
|
private class CustomClassWriter extends ClassWriter {
|
||||||
|
public CustomClassWriter() {
|
||||||
|
super(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClassLoader getClassLoader() {
|
||||||
|
return compiler.getClassLoader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Codegen(TargetStructure clazz, JavaTXCompiler compiler, ASTToTargetAST converter) {
|
public Codegen(TargetStructure clazz, JavaTXCompiler compiler, ASTToTargetAST converter) {
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.className = clazz.qualifiedName().getClassName();
|
this.className = clazz.qualifiedName().getClassName();
|
||||||
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
|
this.cw = new CustomClassWriter();
|
||||||
@Override
|
|
||||||
protected ClassLoader getClassLoader() {
|
|
||||||
return compiler.getClassLoader();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
}
|
}
|
||||||
@@ -82,16 +85,16 @@ public class Codegen {
|
|||||||
int localCounter;
|
int localCounter;
|
||||||
MethodVisitor mv;
|
MethodVisitor mv;
|
||||||
TargetType returnType;
|
TargetType returnType;
|
||||||
// This is used to remember the type from lambda expressions
|
boolean isStatic = false;
|
||||||
TargetType contextType;
|
|
||||||
|
|
||||||
Stack<BreakEnv> breakStack = new Stack<>();
|
Stack<BreakEnv> breakStack = new Stack<>();
|
||||||
Stack<Integer> switchResultValue = new Stack<>();
|
Stack<Integer> switchResultValue = new Stack<>();
|
||||||
|
|
||||||
State(TargetType returnType, MethodVisitor mv, int localCounter) {
|
State(TargetType returnType, MethodVisitor mv, int localCounter, boolean isStatic) {
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.localCounter = localCounter;
|
this.localCounter = localCounter;
|
||||||
|
this.isStatic = isStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterScope() {
|
void enterScope() {
|
||||||
@@ -102,6 +105,10 @@ public class Codegen {
|
|||||||
this.scope = this.scope.parent;
|
this.scope = this.scope.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalVar createVariable(TargetType type) {
|
||||||
|
return createVariable("__var" + this.localCounter, type);
|
||||||
|
}
|
||||||
|
|
||||||
LocalVar createVariable(String name, TargetType type) {
|
LocalVar createVariable(String name, TargetType type) {
|
||||||
var local = new LocalVar(localCounter, name, type);
|
var local = new LocalVar(localCounter, name, type);
|
||||||
scope.add(local);
|
scope.add(local);
|
||||||
@@ -225,9 +232,9 @@ public class Codegen {
|
|||||||
if (source.equals(dest))
|
if (source.equals(dest))
|
||||||
return;
|
return;
|
||||||
if (source.equals(TargetType.Long)) {
|
if (source.equals(TargetType.Long)) {
|
||||||
if (dest.equals(TargetType.Integer)) {
|
if (dest.equals(TargetType.Integer))
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
} else if (dest.equals(TargetType.Float))
|
else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(L2F);
|
mv.visitInsn(L2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(L2D);
|
mv.visitInsn(L2D);
|
||||||
@@ -270,13 +277,45 @@ public class Codegen {
|
|||||||
mv.visitInsn(I2F);
|
mv.visitInsn(I2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(I2D);
|
mv.visitInsn(I2D);
|
||||||
|
} else if (source.equals(TargetType.Boolean)) {
|
||||||
|
unboxPrimitive(state, dest);
|
||||||
|
} else if (isFunctionalInterface(source) && isFunctionalInterface(dest) &&
|
||||||
|
!(source instanceof TargetFunNType && dest instanceof TargetFunNType)) {
|
||||||
|
boxFunctionalInterface(state, source, dest);
|
||||||
} else if (!(dest instanceof TargetGenericType)) {
|
} else if (!(dest instanceof TargetGenericType)) {
|
||||||
boxPrimitive(state, source);
|
//boxPrimitive(state, source);
|
||||||
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
mv.visitTypeInsn(CHECKCAST, dest.getInternalName());
|
||||||
unboxPrimitive(state, dest);
|
unboxPrimitive(state, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record TypePair(TargetType from, TargetType to) {}
|
||||||
|
private Map<TypePair, String> funWrapperClasses = new HashMap<>();
|
||||||
|
|
||||||
|
private void boxFunctionalInterface(State state, TargetType source, TargetType dest) {
|
||||||
|
var mv = state.mv;
|
||||||
|
var className = "FunWrapper$$" +
|
||||||
|
source.name().replaceAll("\\.", "\\$") +
|
||||||
|
"$_$" +
|
||||||
|
dest.name().replaceAll("\\.", "\\$");
|
||||||
|
|
||||||
|
funWrapperClasses.put(new TypePair(source, dest), className);
|
||||||
|
mv.visitTypeInsn(NEW, className);
|
||||||
|
mv.visitInsn(DUP_X1);
|
||||||
|
mv.visitInsn(SWAP);
|
||||||
|
mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(" + source.toDescriptor() + ")V", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFunctionalInterface(TargetType type) {
|
||||||
|
if (type instanceof TargetFunNType) return true;
|
||||||
|
if (type instanceof TargetRefType) {
|
||||||
|
var clazz = compiler.getClass(new JavaClassName(type.name()));
|
||||||
|
return (clazz.getModifiers() & Modifier.INTERFACE) != 0 && clazz.isFunctionalInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private TargetType largerType(TargetType left, TargetType right) {
|
private TargetType largerType(TargetType left, TargetType right) {
|
||||||
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
|
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
|
||||||
return TargetType.String;
|
return TargetType.String;
|
||||||
@@ -723,44 +762,29 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TargetType removeGenerics(TargetType param) {
|
||||||
|
return switch (param) {
|
||||||
|
case null -> null;
|
||||||
|
case TargetFunNType funNType -> new TargetFunNType(funNType.name(), funNType.funNParams(), List.of(), funNType.returnArguments());
|
||||||
|
case TargetRefType refType -> new TargetRefType(refType.name());
|
||||||
|
case TargetGenericType targetGenericType -> TargetType.Object;
|
||||||
|
default -> param;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
|
|
||||||
String methodName = "apply";
|
String methodName = "apply";
|
||||||
TargetMethod.Signature signature = null;
|
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(),
|
||||||
|
lambda.signature().parameters().stream().map(
|
||||||
if (!(state.contextType instanceof TargetFunNType ctx)) {
|
par -> par.withType(TargetType.Object)).toList(),
|
||||||
var intf = compiler.getClass(new JavaClassName(state.contextType.name()));
|
lambda.signature().returnType() != null ? TargetType.Object : null);
|
||||||
if (intf != null) {
|
|
||||||
var method = intf.getMethods().stream().filter(m -> Modifier.isAbstract(m.modifier)).findFirst().orElseThrow();
|
|
||||||
methodName = method.getName();
|
|
||||||
var methodParams = new ArrayList<MethodParameter>();
|
|
||||||
for (var i = 0; i < lambda.signature().parameters().size(); i++) {
|
|
||||||
var param = lambda.signature().parameters().get(i);
|
|
||||||
var tpe = converter.convert(method.getParameterList().getParameterAt(i).getType());
|
|
||||||
methodParams.add(param.withType(tpe));
|
|
||||||
}
|
|
||||||
var retType = converter.convert(method.getReturnType());
|
|
||||||
signature = new TargetMethod.Signature(Set.of(), methodParams, retType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (signature == null) {
|
|
||||||
signature = new TargetMethod.Signature(Set.of(), lambda.signature().parameters().stream().map(par -> par.withType(TargetType.Object)).toList(), TargetType.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
signature = new TargetMethod.Signature(
|
|
||||||
signature.generics(),
|
|
||||||
signature.parameters().stream().map(par ->
|
|
||||||
par.withType(par.pattern().type() instanceof TargetGenericType ? TargetType.Object : par.pattern().type())
|
|
||||||
).toList(),
|
|
||||||
signature.returnType() instanceof TargetGenericType ? TargetType.Object : signature.returnType()
|
|
||||||
);
|
|
||||||
|
|
||||||
var parameters = new ArrayList<>(lambda.captures());
|
var parameters = new ArrayList<>(lambda.captures());
|
||||||
parameters.addAll(signature.parameters());
|
parameters.addAll(signature.parameters());
|
||||||
var implSignature = new TargetMethod.Signature(Set.of(), parameters, lambda.signature().returnType());
|
parameters = parameters.stream().map(param -> param.withType(removeGenerics(param.pattern().type()))).collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
var implSignature = new TargetMethod.Signature(Set.of(), parameters, removeGenerics(lambda.signature().returnType()));
|
||||||
// Normalize
|
|
||||||
|
|
||||||
TargetMethod impl;
|
TargetMethod impl;
|
||||||
if (lambdas.containsKey(lambda)) {
|
if (lambdas.containsKey(lambda)) {
|
||||||
@@ -768,22 +792,22 @@ public class Codegen {
|
|||||||
} else {
|
} else {
|
||||||
var name = "lambda$" + lambdaCounter++;
|
var name = "lambda$" + lambdaCounter++;
|
||||||
|
|
||||||
impl = new TargetMethod(0, name, lambda.block(), implSignature, null);
|
impl = new TargetMethod(state.isStatic ? ACC_STATIC : 0, name, lambda.block(), implSignature, null);
|
||||||
generateMethod(impl);
|
generateMethod(impl, state);
|
||||||
lambdas.put(lambda, impl);
|
lambdas.put(lambda, impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||||
|
|
||||||
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false);
|
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false);
|
||||||
var handle = new Handle(H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||||
|
|
||||||
var params = new ArrayList<TargetType>();
|
var params = new ArrayList<TargetType>();
|
||||||
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||||
|
|
||||||
var descriptor = TargetMethod.getDescriptor(state.contextType, params.toArray(TargetType[]::new));
|
if (!state.isStatic)
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
for (var index = 0; index < lambda.captures().size(); index++) {
|
for (var index = 0; index < lambda.captures().size(); index++) {
|
||||||
var capture = lambda.captures().get(index);
|
var capture = lambda.captures().get(index);
|
||||||
var pattern = (TargetTypePattern) capture.pattern();
|
var pattern = (TargetTypePattern) capture.pattern();
|
||||||
@@ -792,9 +816,42 @@ public class Codegen {
|
|||||||
mv.visitTypeInsn(CHECKCAST, capture.pattern().type().getInternalName());
|
mv.visitTypeInsn(CHECKCAST, capture.pattern().type().getInternalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var descriptor = TargetMethod.getDescriptor(lambda.type(), params.toArray(TargetType[]::new));
|
||||||
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(signature.getSignature()), handle, Type.getType(signature.getDescriptor()));
|
mv.visitInvokeDynamicInsn(methodName, descriptor, bootstrap, Type.getType(signature.getSignature()), handle, Type.getType(signature.getDescriptor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int findReturnCode(TargetType returnType) {
|
||||||
|
if (returnType.equals(TargetType.boolean_)
|
||||||
|
|| returnType.equals(TargetType.char_)
|
||||||
|
|| returnType.equals(TargetType.int_)
|
||||||
|
|| returnType.equals(TargetType.short_)
|
||||||
|
|| returnType.equals(TargetType.byte_))
|
||||||
|
return IRETURN;
|
||||||
|
else if (returnType.equals(TargetType.long_))
|
||||||
|
return LRETURN;
|
||||||
|
else if (returnType.equals(TargetType.float_))
|
||||||
|
return FRETURN;
|
||||||
|
else if (returnType.equals(TargetType.double_))
|
||||||
|
return DRETURN;
|
||||||
|
return ARETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findLoadCode(TargetType loadType) {
|
||||||
|
if (loadType.equals(TargetType.boolean_)
|
||||||
|
|| loadType.equals(TargetType.char_)
|
||||||
|
|| loadType.equals(TargetType.int_)
|
||||||
|
|| loadType.equals(TargetType.short_)
|
||||||
|
|| loadType.equals(TargetType.byte_))
|
||||||
|
return ILOAD;
|
||||||
|
else if (loadType.equals(TargetType.long_))
|
||||||
|
return LLOAD;
|
||||||
|
else if (loadType.equals(TargetType.float_))
|
||||||
|
return FLOAD;
|
||||||
|
else if (loadType.equals(TargetType.double_))
|
||||||
|
return DLOAD;
|
||||||
|
return ALOAD;
|
||||||
|
}
|
||||||
|
|
||||||
private void generate(State state, TargetExpression expr) {
|
private void generate(State state, TargetExpression expr) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
switch (expr) {
|
switch (expr) {
|
||||||
@@ -819,10 +876,7 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetCast cast:
|
case TargetCast cast:
|
||||||
var ctx = state.contextType;
|
|
||||||
state.contextType = cast.type();
|
|
||||||
generate(state, cast.expr());
|
generate(state, cast.expr());
|
||||||
state.contextType = ctx;
|
|
||||||
convertTo(state, cast.expr().type(), cast.type());
|
convertTo(state, cast.expr().type(), cast.type());
|
||||||
break;
|
break;
|
||||||
case TargetInstanceOf instanceOf:
|
case TargetInstanceOf instanceOf:
|
||||||
@@ -867,10 +921,7 @@ public class Codegen {
|
|||||||
case TargetAssign assign: {
|
case TargetAssign assign: {
|
||||||
switch (assign.left()) {
|
switch (assign.left()) {
|
||||||
case TargetLocalVar localVar -> {
|
case TargetLocalVar localVar -> {
|
||||||
var ctype = state.contextType;
|
|
||||||
state.contextType = localVar.type();
|
|
||||||
generate(state, assign.right());
|
generate(state, assign.right());
|
||||||
state.contextType = ctype;
|
|
||||||
|
|
||||||
convertTo(state, assign.right().type(), localVar.type());
|
convertTo(state, assign.right().type(), localVar.type());
|
||||||
boxPrimitive(state, localVar.type());
|
boxPrimitive(state, localVar.type());
|
||||||
@@ -883,10 +934,7 @@ public class Codegen {
|
|||||||
if (!(dot.left() instanceof TargetThis && dot.isStatic()))
|
if (!(dot.left() instanceof TargetThis && dot.isStatic()))
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
|
|
||||||
var ctype = state.contextType;
|
|
||||||
state.contextType = fieldType;
|
|
||||||
generate(state, assign.right());
|
generate(state, assign.right());
|
||||||
state.contextType = ctype;
|
|
||||||
|
|
||||||
convertTo(state, assign.right().type(), fieldType);
|
convertTo(state, assign.right().type(), fieldType);
|
||||||
boxPrimitive(state, fieldType);
|
boxPrimitive(state, fieldType);
|
||||||
@@ -978,6 +1026,27 @@ public class Codegen {
|
|||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TargetDo _do: {
|
||||||
|
Label start = new Label();
|
||||||
|
Label end = new Label();
|
||||||
|
Label check = new Label();
|
||||||
|
|
||||||
|
var env = new BreakEnv();
|
||||||
|
env.startLabel = check;
|
||||||
|
env.endLabel = end;
|
||||||
|
|
||||||
|
mv.visitLabel(start);
|
||||||
|
state.breakStack.push(env);
|
||||||
|
generate(state, _do.body());
|
||||||
|
state.breakStack.pop();
|
||||||
|
|
||||||
|
mv.visitLabel(check);
|
||||||
|
generate(state, _do.cond());
|
||||||
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
|
mv.visitJumpInsn(GOTO, start);
|
||||||
|
mv.visitLabel(end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TargetIf _if: {
|
case TargetIf _if: {
|
||||||
generate(state, _if.cond());
|
generate(state, _if.cond());
|
||||||
Label _else = new Label();
|
Label _else = new Label();
|
||||||
@@ -995,29 +1064,12 @@ public class Codegen {
|
|||||||
case TargetReturn ret: {
|
case TargetReturn ret: {
|
||||||
if (ret.expression() != null && state.returnType != null) {
|
if (ret.expression() != null && state.returnType != null) {
|
||||||
if (state.returnType instanceof TargetPrimitiveType) {
|
if (state.returnType instanceof TargetPrimitiveType) {
|
||||||
var ctype = state.contextType;
|
|
||||||
state.contextType = state.returnType;
|
|
||||||
generate(state, ret.expression());
|
generate(state, ret.expression());
|
||||||
state.contextType = ctype;
|
|
||||||
|
|
||||||
unboxPrimitive(state, state.returnType);
|
unboxPrimitive(state, state.returnType);
|
||||||
if (state.returnType.equals(TargetType.boolean_)
|
mv.visitInsn(findReturnCode(state.returnType));
|
||||||
|| state.returnType.equals(TargetType.char_)
|
|
||||||
|| state.returnType.equals(TargetType.int_)
|
|
||||||
|| state.returnType.equals(TargetType.short_)
|
|
||||||
|| state.returnType.equals(TargetType.byte_))
|
|
||||||
mv.visitInsn(IRETURN);
|
|
||||||
else if (state.returnType.equals(TargetType.long_))
|
|
||||||
mv.visitInsn(LRETURN);
|
|
||||||
else if (state.returnType.equals(TargetType.float_))
|
|
||||||
mv.visitInsn(FRETURN);
|
|
||||||
else if (state.returnType.equals(TargetType.double_))
|
|
||||||
mv.visitInsn(DRETURN);
|
|
||||||
} else {
|
} else {
|
||||||
var ctype = state.contextType;
|
|
||||||
state.contextType = state.returnType;
|
|
||||||
generate(state, ret.expression());
|
generate(state, ret.expression());
|
||||||
state.contextType = ctype;
|
|
||||||
boxPrimitive(state, ret.expression().type());
|
boxPrimitive(state, ret.expression().type());
|
||||||
convertTo(state, ret.expression().type(), state.returnType);
|
convertTo(state, ret.expression().type(), state.returnType);
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
@@ -1068,12 +1120,10 @@ public class Codegen {
|
|||||||
for (var i = 0; i < call.args().size(); i++) {
|
for (var i = 0; i < call.args().size(); i++) {
|
||||||
var e = call.args().get(i);
|
var e = call.args().get(i);
|
||||||
var arg = call.parameterTypes().get(i);
|
var arg = call.parameterTypes().get(i);
|
||||||
var ctype = state.contextType;
|
|
||||||
state.contextType = arg;
|
|
||||||
generate(state, e);
|
generate(state, e);
|
||||||
|
convertTo(state, e.type(), arg);
|
||||||
if (!(arg instanceof TargetPrimitiveType))
|
if (!(arg instanceof TargetPrimitiveType))
|
||||||
boxPrimitive(state, e.type());
|
boxPrimitive(state, e.type());
|
||||||
state.contextType = ctype;
|
|
||||||
}
|
}
|
||||||
var descriptor = call.getDescriptor();
|
var descriptor = call.getDescriptor();
|
||||||
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
||||||
@@ -1259,8 +1309,7 @@ public class Codegen {
|
|||||||
state.enterScope();
|
state.enterScope();
|
||||||
// This is the index to start the switch from
|
// This is the index to start the switch from
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
if (aSwitch.isExpression())
|
state.pushSwitch();
|
||||||
state.pushSwitch();
|
|
||||||
|
|
||||||
// To be able to skip ahead to the next case
|
// To be able to skip ahead to the next case
|
||||||
var start = new Label();
|
var start = new Label();
|
||||||
@@ -1274,16 +1323,17 @@ public class Codegen {
|
|||||||
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class);
|
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class);
|
||||||
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/runtime/SwitchBootstraps", "typeSwitch", mt.toMethodDescriptorString(), false);
|
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/runtime/SwitchBootstraps", "typeSwitch", mt.toMethodDescriptorString(), false);
|
||||||
|
|
||||||
var types = new ArrayList<Object>(aSwitch.cases().size());
|
var types = new ArrayList<>(aSwitch.cases().size());
|
||||||
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
|
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
|
||||||
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern)
|
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern) {
|
||||||
types.add(Type.getObjectType(label.type().getInternalName()));
|
if (label.type() instanceof TargetGenericType) types.add(Type.getType(Object.class));
|
||||||
else if (label instanceof TargetLiteral lit)
|
else types.add(Type.getObjectType(label.type().getInternalName()));
|
||||||
|
} else if (label instanceof TargetLiteral lit) {
|
||||||
types.add(lit.value());
|
types.add(lit.value());
|
||||||
else if (label instanceof TargetGuard guard)
|
} else if (label instanceof TargetGuard guard) {
|
||||||
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
||||||
// TODO Same here we need to evaluate constant;
|
// TODO Same here we need to evaluate constant;
|
||||||
else {
|
} else {
|
||||||
System.out.println(label);
|
System.out.println(label);
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@@ -1304,11 +1354,7 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultLabel = end;
|
var defaultLabel = new Label();
|
||||||
if (aSwitch.default_() != null) {
|
|
||||||
defaultLabel = new Label();
|
|
||||||
}
|
|
||||||
|
|
||||||
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
|
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
|
||||||
|
|
||||||
for (var i = 0; i < aSwitch.cases().size(); i++) {
|
for (var i = 0; i < aSwitch.cases().size(); i++) {
|
||||||
@@ -1343,11 +1389,18 @@ public class Codegen {
|
|||||||
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
|
if (aSwitch.isExpression()) mv.visitJumpInsn(GOTO, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mv.visitLabel(defaultLabel);
|
||||||
if (aSwitch.default_() != null) {
|
if (aSwitch.default_() != null) {
|
||||||
mv.visitLabel(defaultLabel);
|
|
||||||
generate(state, aSwitch.default_().body());
|
generate(state, aSwitch.default_().body());
|
||||||
if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression())
|
if (aSwitch.default_().isSingleExpression() && aSwitch.isExpression())
|
||||||
yieldValue(state, aSwitch.default_().body().statements().get(0).type());
|
yieldValue(state, aSwitch.default_().body().statements().get(0).type());
|
||||||
|
} else {
|
||||||
|
// throw illegal argument exception on missing default case
|
||||||
|
mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
mv.visitLdcInsn("Unhandled case value");
|
||||||
|
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false);
|
||||||
|
mv.visitInsn(ATHROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
@@ -1355,8 +1408,10 @@ public class Codegen {
|
|||||||
|
|
||||||
state.breakStack.pop();
|
state.breakStack.pop();
|
||||||
if (aSwitch.isExpression()) {
|
if (aSwitch.isExpression()) {
|
||||||
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
if (aSwitch.type() != null) {
|
||||||
unboxPrimitive(state, aSwitch.type());
|
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||||
|
unboxPrimitive(state, aSwitch.type());
|
||||||
|
}
|
||||||
state.popSwitch();
|
state.popSwitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1367,30 +1422,50 @@ public class Codegen {
|
|||||||
if (i >= clazz.getFieldDecl().size())
|
if (i >= clazz.getFieldDecl().size())
|
||||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||||
var field = clazz.getFieldDecl().get(i);
|
var field = clazz.getFieldDecl().get(i);
|
||||||
var fieldType = new TargetRefType(((RefType) field.getType()).getName().toString());
|
var fieldType = converter.convert(field.getType());
|
||||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
||||||
if (pat.type() instanceof TargetPrimitiveType)
|
if (pat.type() instanceof TargetPrimitiveType)
|
||||||
boxPrimitive(state, pat.type());
|
boxPrimitive(state, pat.type());
|
||||||
|
|
||||||
state.mv.visitInsn(DUP);
|
if (pat.type() instanceof TargetRefType) {
|
||||||
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
state.mv.visitInsn(DUP);
|
||||||
|
state.mv.visitTypeInsn(INSTANCEOF, pat.type().getInternalName());
|
||||||
|
|
||||||
var cont = new Label();
|
var cont = new Label();
|
||||||
state.mv.visitJumpInsn(IFNE, cont);
|
state.mv.visitJumpInsn(IFNE, cont);
|
||||||
for (var i = 0; i < depth; i++) {
|
for (var i = 0; i < depth; i++) {
|
||||||
state.mv.visitInsn(POP);
|
state.mv.visitInsn(POP);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||||
|
state.mv.visitLdcInsn(index + 1);
|
||||||
|
state.mv.visitJumpInsn(GOTO, start);
|
||||||
|
state.mv.visitLabel(cont);
|
||||||
|
|
||||||
|
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
|
||||||
}
|
}
|
||||||
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
|
||||||
state.mv.visitLdcInsn(index + 1);
|
|
||||||
state.mv.visitJumpInsn(GOTO, start);
|
|
||||||
state.mv.visitLabel(cont);
|
|
||||||
|
|
||||||
state.mv.visitTypeInsn(CHECKCAST, pat.type().getInternalName());
|
if (pat instanceof TargetExpressionPattern ep) {
|
||||||
|
var cur = state.createVariable(pat.type());
|
||||||
|
state.mv.visitVarInsn(ASTORE, cur.index);
|
||||||
|
|
||||||
if (pat instanceof TargetTypePattern sp) {
|
var expr = new Equal(pat.type(), new TargetLocalVar(cur.type, cur.name), ep.expression());
|
||||||
|
generate(state, expr);
|
||||||
|
|
||||||
|
var cont = new Label();
|
||||||
|
state.mv.visitJumpInsn(IFNE, cont);
|
||||||
|
for (var i = 0; i < depth - 1; i++) {
|
||||||
|
state.mv.visitInsn(POP);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||||
|
state.mv.visitLdcInsn(index + 1);
|
||||||
|
state.mv.visitJumpInsn(GOTO, start);
|
||||||
|
state.mv.visitLabel(cont);
|
||||||
|
} else if (pat instanceof TargetTypePattern sp) {
|
||||||
var local = state.createVariable(sp.name(), sp.type());
|
var local = state.createVariable(sp.name(), sp.type());
|
||||||
state.mv.visitVarInsn(ASTORE, local.index);
|
state.mv.visitVarInsn(ASTORE, local.index);
|
||||||
} else if (pat instanceof TargetComplexPattern cp) {
|
} else if (pat instanceof TargetComplexPattern cp) {
|
||||||
@@ -1405,10 +1480,27 @@ public class Codegen {
|
|||||||
// TODO Check if class is a Record
|
// TODO Check if class is a Record
|
||||||
|
|
||||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||||
state.mv.visitInsn(DUP);
|
|
||||||
|
|
||||||
var subPattern = cp.subPatterns().get(i);
|
var subPattern = cp.subPatterns().get(i);
|
||||||
|
|
||||||
|
state.mv.visitInsn(DUP);
|
||||||
extractField(state, cp.type(), i, clazz);
|
extractField(state, cp.type(), i, clazz);
|
||||||
|
|
||||||
|
if (subPattern.type() instanceof TargetRefType || subPattern.type() instanceof TargetExtendsWildcard) {
|
||||||
|
state.mv.visitInsn(DUP);
|
||||||
|
state.mv.visitTypeInsn(INSTANCEOF, subPattern.type().getInternalName());
|
||||||
|
|
||||||
|
var cont = new Label();
|
||||||
|
state.mv.visitJumpInsn(IFNE, cont);
|
||||||
|
for (var j = 0; j < depth + 1; j++) {
|
||||||
|
state.mv.visitInsn(POP);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
||||||
|
state.mv.visitLdcInsn(index + 1);
|
||||||
|
state.mv.visitJumpInsn(GOTO, start);
|
||||||
|
state.mv.visitLabel(cont);
|
||||||
|
}
|
||||||
|
|
||||||
bindPattern(state, subPattern.type(), subPattern, start, index, depth + 1);
|
bindPattern(state, subPattern.type(), subPattern, start, index, depth + 1);
|
||||||
}
|
}
|
||||||
state.mv.visitInsn(POP);
|
state.mv.visitInsn(POP);
|
||||||
@@ -1443,7 +1535,7 @@ public class Codegen {
|
|||||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
var state = new State(null, mv, 0);
|
var state = new State(null, mv, 0, true);
|
||||||
generate(state, constructor.block());
|
generate(state, constructor.block());
|
||||||
|
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
@@ -1457,7 +1549,7 @@ public class Codegen {
|
|||||||
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(null, mv, 1);
|
var state = new State(null, mv, 1, false);
|
||||||
for (var param : constructor.parameters()) {
|
for (var param : constructor.parameters()) {
|
||||||
var pattern = param.pattern();
|
var pattern = param.pattern();
|
||||||
if (pattern instanceof TargetTypePattern tp)
|
if (pattern instanceof TargetTypePattern tp)
|
||||||
@@ -1481,33 +1573,53 @@ public class Codegen {
|
|||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int bindLocalVariables(State state, TargetPattern pattern, int offset, int field) {
|
private void bindLocalVariables(State state, TargetComplexPattern cp, int offset) {
|
||||||
if (pattern instanceof TargetComplexPattern cp) {
|
state.mv.visitVarInsn(ALOAD, offset);
|
||||||
state.mv.visitVarInsn(ALOAD, offset);
|
|
||||||
|
|
||||||
var clazz = findClass(new JavaClassName(cp.type().name()));
|
var clazz = findClass(new JavaClassName(cp.type().name()));
|
||||||
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
if (clazz == null) throw new CodeGenException("Class definition for '" + cp.type().name() + "' not found");
|
||||||
|
|
||||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||||
var subPattern = cp.subPatterns().get(i);
|
var subPattern = cp.subPatterns().get(i);
|
||||||
|
|
||||||
if (i < cp.subPatterns().size() - 1)
|
if (i < cp.subPatterns().size() - 1)
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
|
|
||||||
extractField(state, cp.type(), i, clazz);
|
extractField(state, cp.type(), i, clazz);
|
||||||
|
if (subPattern.type() instanceof TargetRefType)
|
||||||
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
||||||
state.mv.visitVarInsn(ASTORE, offset);
|
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
||||||
offset = bindLocalVariables(state, subPattern, offset, i);
|
state.mv.visitVarInsn(ASTORE, offset);
|
||||||
|
if (subPattern instanceof TargetComplexPattern cp2) {
|
||||||
|
bindLocalVariables(state, cp2, offset);
|
||||||
}
|
}
|
||||||
} else if (pattern instanceof TargetTypePattern tp) {
|
}
|
||||||
offset++;
|
}
|
||||||
state.createVariable(tp.name(), tp.type());
|
private void generateMethod(TargetMethod method) {
|
||||||
} else throw new NotImplementedException();
|
generateMethod(method, null);
|
||||||
return offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateMethod(TargetMethod method) {
|
private void generateMainMethod() {
|
||||||
|
var mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
|
||||||
|
mv.visitCode();
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, className, "main", "(Ljava/util/List;)V", false);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateMethod(TargetMethod method, State parent) {
|
||||||
var access = method.access();
|
var access = method.access();
|
||||||
|
|
||||||
|
var params = method.signature().parameters();
|
||||||
|
if (method.name().equals("main") && method.isStatic() && params.size() == 1 &&
|
||||||
|
params.getFirst().pattern().type().equals(new TargetRefType("java.util.List", List.of(new TargetRefType("java.lang.String"))))) {
|
||||||
|
|
||||||
|
generateMainMethod();
|
||||||
|
}
|
||||||
|
|
||||||
if (method.block() == null)
|
if (method.block() == null)
|
||||||
access |= ACC_ABSTRACT;
|
access |= ACC_ABSTRACT;
|
||||||
if (clazz instanceof TargetInterface)
|
if (clazz instanceof TargetInterface)
|
||||||
@@ -1521,10 +1633,21 @@ public class Codegen {
|
|||||||
|
|
||||||
if (method.block() != null) {
|
if (method.block() != null) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1);
|
var state = new State(method.signature().returnType(), mv, method.isStatic() ? 0 : 1, method.isStatic());
|
||||||
for (var param : method.signature().parameters()) {
|
if (parent != null) {
|
||||||
bindLocalVariables(state, param.pattern(), 1, 0);
|
state.scope.parent = parent.scope;
|
||||||
}
|
}
|
||||||
|
var offset = 1;
|
||||||
|
for (var param : method.signature().parameters()) {
|
||||||
|
state.createVariable(param.pattern().name(), param.pattern().type());
|
||||||
|
}
|
||||||
|
for (var param : method.signature().parameters()) {
|
||||||
|
if (param.pattern() instanceof TargetComplexPattern cp)
|
||||||
|
bindLocalVariables(state, cp, offset);
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
//if (parent != null) System.out.println("parent: " + parent.scope.locals.keySet());
|
||||||
|
//System.out.println(state.scope.locals.keySet());
|
||||||
generate(state, method.block());
|
generate(state, method.block());
|
||||||
if (method.signature().returnType() == null)
|
if (method.signature().returnType() == null)
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
@@ -1558,13 +1681,26 @@ public class Codegen {
|
|||||||
if (!(clazz instanceof TargetInterface))
|
if (!(clazz instanceof TargetInterface))
|
||||||
access |= ACC_SUPER;
|
access |= ACC_SUPER;
|
||||||
|
|
||||||
|
// Check sealed
|
||||||
|
for (var intf : clazz.implementingInterfaces()) {
|
||||||
|
var intfClass = compiler.getClass(new JavaClassName(intf.name()));
|
||||||
|
if (intfClass.isSealed()) {
|
||||||
|
if (intfClass.getPermittedSubtypes().stream().noneMatch(type -> type.getName().equals(new JavaClassName(className)))) {
|
||||||
|
throw new CodeGenException("Sealed interface " + intfClass.getClassName() + " doesn't permit class " + className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var signature = generateSignature(clazz, clazz.generics());
|
var signature = generateSignature(clazz, clazz.generics());
|
||||||
var interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new);
|
var interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new);
|
||||||
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";
|
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";
|
||||||
|
|
||||||
cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces);
|
cw.visit(V1_8, access, clazz.qualifiedName().toString().replaceAll("\\.", "/"), signature, superType, interfaces);
|
||||||
if (clazz.txGenerics() != null && signature != null)
|
if (clazz.txGenerics() != null && signature != null) {
|
||||||
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
var txSignature = generateSignature(clazz, clazz.txGenerics());
|
||||||
|
if (txSignature != null)
|
||||||
|
cw.visitAttribute(new JavaTXSignatureAttribute(txSignature));
|
||||||
|
}
|
||||||
|
|
||||||
clazz.fields().forEach(this::generateField);
|
clazz.fields().forEach(this::generateField);
|
||||||
clazz.constructors().forEach(this::generateConstructor);
|
clazz.constructors().forEach(this::generateConstructor);
|
||||||
@@ -1576,6 +1712,85 @@ public class Codegen {
|
|||||||
if (clazz instanceof TargetRecord)
|
if (clazz instanceof TargetRecord)
|
||||||
generateRecordMethods();
|
generateRecordMethods();
|
||||||
|
|
||||||
|
// Generate wrapper classes for function types
|
||||||
|
for (var pair : funWrapperClasses.keySet()) {
|
||||||
|
var className = funWrapperClasses.get(pair);
|
||||||
|
ClassWriter cw2 = new CustomClassWriter();
|
||||||
|
cw2.visit(V1_8, ACC_PUBLIC, className, null, "java/lang/Object", new String[] { pair.to.getInternalName() });
|
||||||
|
cw2.visitField(ACC_PRIVATE, "wrapped", pair.from.toDescriptor(), null, null).visitEnd();
|
||||||
|
|
||||||
|
// Generate constructor
|
||||||
|
var ctor = cw2.visitMethod(ACC_PUBLIC, "<init>", "(" + pair.from.toDescriptor() + ")V", null, null);
|
||||||
|
ctor.visitVarInsn(ALOAD, 0);
|
||||||
|
ctor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||||
|
ctor.visitVarInsn(ALOAD, 0);
|
||||||
|
ctor.visitVarInsn(ALOAD, 1);
|
||||||
|
ctor.visitFieldInsn(PUTFIELD, className, "wrapped", pair.from.toDescriptor());
|
||||||
|
ctor.visitInsn(RETURN);
|
||||||
|
ctor.visitMaxs(0, 0);
|
||||||
|
ctor.visitEnd();
|
||||||
|
|
||||||
|
String methodName = "apply";
|
||||||
|
String fromDescriptor = null;
|
||||||
|
TargetType fromReturn = null;
|
||||||
|
if (!(pair.from instanceof TargetFunNType funNType)) {
|
||||||
|
var fromClass = compiler.getClass(new JavaClassName(pair.from.name()));
|
||||||
|
var fromMethod = fromClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
|
||||||
|
methodName = fromMethod.name;
|
||||||
|
|
||||||
|
fromReturn = converter.convert(fromMethod.getReturnType());
|
||||||
|
var fromParams = converter.convert(fromMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
||||||
|
fromDescriptor = TargetMethod.getDescriptor(fromReturn, fromParams);
|
||||||
|
} else {
|
||||||
|
fromReturn = funNType.returnArguments() > 0 ? TargetType.Object : null;
|
||||||
|
fromDescriptor = funNType.toMethodDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
var toClass = compiler.getClass(new JavaClassName(pair.to.name()));
|
||||||
|
var toMethod = toClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
|
||||||
|
var toReturn = converter.convert(toMethod.getReturnType());
|
||||||
|
var toParams = converter.convert(toMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
||||||
|
var toDescriptor = TargetMethod.getDescriptor(toReturn, toParams);
|
||||||
|
|
||||||
|
// Generate wrapper method
|
||||||
|
var mv = cw2.visitMethod(ACC_PUBLIC, toMethod.name, toDescriptor, null, null);
|
||||||
|
var state = new State(null, mv, 0, false);
|
||||||
|
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitFieldInsn(GETFIELD, className, "wrapped", pair.from.toDescriptor());
|
||||||
|
for (var i = 0; i < toParams.length; i++) {
|
||||||
|
var arg = toParams[i];
|
||||||
|
mv.visitVarInsn(findLoadCode(arg), i + 1);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(INVOKEINTERFACE, pair.from.getInternalName(), methodName, fromDescriptor, true);
|
||||||
|
if (fromReturn != null) {
|
||||||
|
if (toReturn instanceof TargetPrimitiveType) {
|
||||||
|
convertTo(state, fromReturn, TargetType.toWrapper(toReturn));
|
||||||
|
} else convertTo(state, fromReturn, toReturn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toReturn != null)
|
||||||
|
mv.visitInsn(findReturnCode(toReturn));
|
||||||
|
|
||||||
|
else mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
|
mv.visitEnd();
|
||||||
|
|
||||||
|
cw2.visitEnd();
|
||||||
|
var bytes = cw2.toByteArray();
|
||||||
|
converter.auxiliaries.put(className, bytes);
|
||||||
|
|
||||||
|
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
||||||
|
// Instead we should just look at the folder.
|
||||||
|
try {
|
||||||
|
converter.classLoader.findClass(className);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
try {
|
||||||
|
converter.classLoader.loadClass(className, bytes);
|
||||||
|
} catch (LinkageError ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cw.visitEnd();
|
cw.visitEnd();
|
||||||
return cw.toByteArray();
|
return cw.toByteArray();
|
||||||
}
|
}
|
||||||
@@ -1606,7 +1821,7 @@ public class Codegen {
|
|||||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||||
for (var i = 0; i < clazz.fields().size(); i++) {
|
for (var i = 0; i < clazz.fields().size(); i++) {
|
||||||
var field = clazz.fields().get(i);
|
var field = clazz.fields().get(i);
|
||||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
|
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false);
|
||||||
bootstrapArgs[i + 2] = fieldRef;
|
bootstrapArgs[i + 2] = fieldRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Break;
|
||||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.sql.Array;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -33,6 +35,40 @@ public class FunNGenerator {
|
|||||||
public static class GenericParameters {
|
public static class GenericParameters {
|
||||||
int start;
|
int start;
|
||||||
public List<TargetType> parameters = new ArrayList<>();
|
public List<TargetType> parameters = new ArrayList<>();
|
||||||
|
final String descriptor;
|
||||||
|
public final List<TargetType> inParams;
|
||||||
|
public final List<TargetType> realParams;
|
||||||
|
|
||||||
|
public GenericParameters(TargetFunNType funNType) {
|
||||||
|
this(funNType.funNParams(), funNType.returnArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericParameters(List<TargetType> params, int numReturns) {
|
||||||
|
this.realParams = params;
|
||||||
|
this.inParams = flattenTypeParams(params);
|
||||||
|
var type = new TargetRefType(FunNGenerator.getSuperClassName(params.size() - 1, numReturns), params);
|
||||||
|
descriptor = applyDescriptor(type, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<TargetType> flattenTypeParams(List<TargetType> params) {
|
||||||
|
var res = new ArrayList<TargetType>();
|
||||||
|
for (var param : params) {
|
||||||
|
if (param instanceof TargetSpecializedType tspec) {
|
||||||
|
res.addAll(flattenTypeParams(tspec.params()));
|
||||||
|
} else {
|
||||||
|
res.add(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetType getReturnType() {
|
||||||
|
return FunNGenerator.getReturnType(realParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TargetType> getArguments() {
|
||||||
|
return FunNGenerator.getArguments(realParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String applyDescriptor(TargetType type, GenericParameters gep) {
|
private static String applyDescriptor(TargetType type, GenericParameters gep) {
|
||||||
@@ -69,7 +105,7 @@ public class FunNGenerator {
|
|||||||
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
return applyNameDescriptor(type).replace("/", "$").replace(";", "$_$");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] generateSuperBytecode(int numberArguments) {
|
public static byte[] generateSuperBytecode(int numberArguments, int numReturnTypes) {
|
||||||
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
StringBuilder superFunNClassSignature = new StringBuilder("<");
|
||||||
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
StringBuilder superFunNMethodSignature = new StringBuilder("(");
|
||||||
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
StringBuilder superFunNMethodDescriptor = new StringBuilder("(");
|
||||||
@@ -80,30 +116,34 @@ public class FunNGenerator {
|
|||||||
superFunNMethodDescriptor.append(objectSignature);
|
superFunNMethodDescriptor.append(objectSignature);
|
||||||
}
|
}
|
||||||
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
superFunNClassSignature.append(String.format("%s:%s>%s", returnGeneric, objectSignature, objectSignature));
|
||||||
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
|
if (numReturnTypes > 0) {
|
||||||
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
superFunNMethodSignature.append(String.format(")T%s;", returnGeneric));
|
||||||
|
superFunNMethodDescriptor.append(String.format(")%s", objectSignature));
|
||||||
|
} else {
|
||||||
|
superFunNMethodSignature.append(")V");
|
||||||
|
superFunNMethodDescriptor.append(")V");
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println(superFunNMethodSignature);
|
System.out.println(superFunNMethodSignature);
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments), superFunNClassSignature.toString(), objectSuperType, null);
|
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSuperClassName(numberArguments, numReturnTypes), superFunNClassSignature.toString(), objectSuperType, null);
|
||||||
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
|
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor.toString(), superFunNMethodSignature.toString(), null);
|
||||||
methodVisitor.visitEnd();
|
methodVisitor.visitEnd();
|
||||||
classWriter.visitEnd();
|
classWriter.visitEnd();
|
||||||
return classWriter.toByteArray();
|
return classWriter.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSuperClassName(int numberArguments) {
|
public static String getSuperClassName(int numberArguments, int returnArguments) {
|
||||||
return String.format("Fun%d$$", numberArguments);
|
return returnArguments > 0 ? String.format("Fun%d$$", numberArguments) : String.format("FunVoid%d$$", numberArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] generateSpecializedBytecode(List<TargetType> argumentTypes, TargetType returnType, GenericParameters gep) {
|
public static byte[] generateSpecializedBytecode(GenericParameters gep, List<String> superInterfaces) {
|
||||||
List<TargetType> parameters = Stream
|
var argumentTypes = gep.getArguments();
|
||||||
.concat(argumentTypes.stream(), Stream.of(returnType))
|
var returnType = gep.getReturnType();
|
||||||
.toList();
|
|
||||||
|
|
||||||
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applyDescriptor(new TargetRefType(getSuperClassName(argumentTypes.size()), parameters), gep));
|
StringBuilder funNClassSignature = new StringBuilder(objectSignature + gep.descriptor);
|
||||||
boolean containsGeneric = false;
|
boolean containsGeneric = false;
|
||||||
|
|
||||||
String genericSignature = "<";
|
String genericSignature = "<";
|
||||||
@@ -114,10 +154,18 @@ public class FunNGenerator {
|
|||||||
|
|
||||||
genericSignature += ">";
|
genericSignature += ">";
|
||||||
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
|
if (containsGeneric) funNClassSignature.insert(0, genericSignature);
|
||||||
System.out.println(funNClassSignature.toString());
|
|
||||||
|
for (var superInterface : superInterfaces) {
|
||||||
|
funNClassSignature.append('L');
|
||||||
|
funNClassSignature.append(superInterface);
|
||||||
|
funNClassSignature.append(';');
|
||||||
|
}
|
||||||
|
|
||||||
|
var interfaces = new ArrayList<>(superInterfaces);
|
||||||
|
interfaces.add(getSuperClassName(argumentTypes.size(), returnType != null ? 1 : 0));
|
||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
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.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getSpecializedClassName(argumentTypes, returnType), funNClassSignature.toString(), objectSuperType, interfaces.toArray(String[]::new));
|
||||||
classWriter.visitEnd();
|
classWriter.visitEnd();
|
||||||
return classWriter.toByteArray();
|
return classWriter.toByteArray();
|
||||||
}
|
}
|
||||||
@@ -133,14 +181,24 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSpecializedClassName(GenericParameters gep) {
|
||||||
|
return getSpecializedClassName(gep.getArguments(), gep.getReturnType());
|
||||||
|
}
|
||||||
|
|
||||||
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
public static String getSpecializedClassName(List<TargetType> argumentTypes, TargetType returnType) {
|
||||||
return String.format("Fun%d$$%s%s",
|
var arguments = argumentTypes
|
||||||
|
.stream()
|
||||||
|
.map(FunNGenerator::encodeType)
|
||||||
|
.collect(Collectors.joining());
|
||||||
|
|
||||||
|
if (returnType != null)
|
||||||
|
return String.format("Fun%d$$%s%s",
|
||||||
|
argumentTypes.size(),
|
||||||
|
arguments,
|
||||||
|
encodeType(returnType));
|
||||||
|
else return String.format("FunVoidImpl%d$$%s",
|
||||||
argumentTypes.size(),
|
argumentTypes.size(),
|
||||||
argumentTypes
|
arguments);
|
||||||
.stream()
|
|
||||||
.map(FunNGenerator::encodeType)
|
|
||||||
.collect(Collectors.joining()),
|
|
||||||
encodeType(returnType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<TargetType> getArguments(List<TargetType> list) {
|
public static List<TargetType> getArguments(List<TargetType> list) {
|
||||||
@@ -151,8 +209,8 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static TargetType getReturnType(List<TargetType> list) {
|
public static TargetType getReturnType(List<TargetType> list) {
|
||||||
if(list.size() == 0)
|
if(list.isEmpty())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
return list.get(list.size() - 1);
|
return list.getLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import de.dhbwstuttgart.bytecode.Codegen;
|
|||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
@@ -66,7 +67,7 @@ public class JavaTXCompiler {
|
|||||||
Boolean resultmodel = true;
|
Boolean resultmodel = true;
|
||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||||
|
|
||||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
Boolean log = false; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
public final DirectoryClassLoader classLoader;
|
public final DirectoryClassLoader classLoader;
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
if (outputPath != null) path.add(outputPath);
|
if (outputPath != null) path.add(outputPath);
|
||||||
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
|
classLoader = new DirectoryClassLoader(path, ClassLoader.getSystemClassLoader());
|
||||||
environment = new CompilationEnvironment(sources);
|
environment = new CompilationEnvironment(sources, classLoader);
|
||||||
classPath = path;
|
classPath = path;
|
||||||
this.outputPath = outputPath;
|
this.outputPath = outputPath;
|
||||||
|
|
||||||
@@ -327,74 +328,6 @@ public class JavaTXCompiler {
|
|||||||
logFile.write(ASTTypePrinter.print(f));
|
logFile.write(ASTTypePrinter.print(f));
|
||||||
}
|
}
|
||||||
logFile.flush();
|
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> varianceTPHold;
|
||||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
@@ -461,86 +394,12 @@ public class JavaTXCompiler {
|
|||||||
logFile.write(ASTTypePrinter.print(sf));
|
logFile.write(ASTTypePrinter.print(sf));
|
||||||
System.out.println(ASTTypePrinter.print(sf));
|
System.out.println(ASTTypePrinter.print(sf));
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
|
List<UnifyPair> andConstraintsSorted = unifyCons.getUndConstraints().stream()
|
||||||
|
.sorted(Comparator.comparing(UnifyPair::getPairOp).thenComparing(UnifyPair::getLhsType, Comparator.comparing(UnifyType::getName)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
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) -> {
|
System.out.println(andConstraintsSorted);
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
}, (a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
});
|
|
||||||
|
|
||||||
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist().stream().filter(z -> z.getType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce(new HashSet<String>(), (a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
}, (a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
})).reduce(new HashSet<String>(), (a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
});
|
|
||||||
|
|
||||||
Set<String> paraTypeVarNames = methodParaTypeVarNames;
|
|
||||||
paraTypeVarNames.addAll(constructorParaTypeVarNames);
|
|
||||||
|
|
||||||
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
}).get();
|
|
||||||
|
|
||||||
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder).map(z -> ((TypePlaceholder) z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a, b) -> {
|
|
||||||
a.addAll(b);
|
|
||||||
return a;
|
|
||||||
}).get();
|
|
||||||
|
|
||||||
returnTypeVarNames.addAll(fieldTypeVarNames);
|
|
||||||
|
|
||||||
unifyCons = unifyCons.map(x -> {
|
|
||||||
// Hier muss ueberlegt werden, ob
|
|
||||||
// 1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
|
||||||
// mit disableWildcardtable() werden.
|
|
||||||
// 2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
|
||||||
// in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
|
||||||
// PL 2018-04-23
|
|
||||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
|
||||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
|
||||||
((PlaceholderType) x.getLhsType()).setVariance((byte) 1);
|
|
||||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
|
||||||
((PlaceholderType) x.getLhsType()).setVariance((byte) -1);
|
|
||||||
((PlaceholderType) x.getLhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
|
||||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
|
||||||
((PlaceholderType) x.getRhsType()).setVariance((byte) 1);
|
|
||||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
|
||||||
((PlaceholderType) x.getRhsType()).setVariance((byte) -1);
|
|
||||||
((PlaceholderType) x.getRhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
|
||||||
// JEWEILS ANDERE SEITE
|
|
||||||
});
|
|
||||||
|
|
||||||
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
|
|
||||||
// variance 1 gesetzt
|
|
||||||
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
|
|
||||||
// Parameter die Typen der Argumente links stehen
|
|
||||||
// und die Typen der Rückgabewerte immer rechts stehen
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> { if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { ((PlaceholderType) x.getLhsType()).setVariance((byte)1); } else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) { ((PlaceholderType) x.getRhsType()).setVariance((byte)-1); } })));
|
|
||||||
*/
|
|
||||||
|
|
||||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
|
||||||
Set<PlaceholderType> varianceTPHold;
|
Set<PlaceholderType> varianceTPHold;
|
||||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
@@ -563,7 +422,14 @@ public class JavaTXCompiler {
|
|||||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||||
urm.addUnifyResultListener(li);
|
urm.addUnifyResultListener(li);
|
||||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||||
System.out.println("RESULT Final: " + li.getResults());
|
//System.out.println("RESULT Final: " + li.getResults());
|
||||||
|
var finalResults = li.getResults().stream().sorted().toList();
|
||||||
|
int i = 0;
|
||||||
|
System.out.println("RESULT Final: ");
|
||||||
|
for (var result : finalResults){
|
||||||
|
System.out.println("Result: " + i++);
|
||||||
|
System.out.println(result.getSortedResults());
|
||||||
|
}
|
||||||
System.out.println("Constraints for Generated Generics: " + " ???");
|
System.out.println("Constraints for Generated Generics: " + " ???");
|
||||||
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
@@ -604,6 +470,85 @@ public class JavaTXCompiler {
|
|||||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TEMPORARY - Only for Language Server Usage
|
||||||
|
*/
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
|
||||||
|
var sf = sourceFiles.get(file);
|
||||||
|
if(sf == null){
|
||||||
|
sf = sourceFiles.values().stream().findFirst().get();
|
||||||
|
}
|
||||||
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
allClasses.addAll(getAvailableClasses(sf));
|
||||||
|
allClasses.addAll(sf.getClasses());
|
||||||
|
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
||||||
|
for (var clazz : newClasses) {
|
||||||
|
// Don't load classes that get recompiled
|
||||||
|
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
||||||
|
continue;
|
||||||
|
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
||||||
|
allClasses.add(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ConstraintSet<Pair> cons = getConstraints(file);
|
||||||
|
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||||
|
try {
|
||||||
|
Writer logFile = new OutputStreamWriter(new NullOutputStream());
|
||||||
|
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
||||||
|
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, 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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
unifyCons = unifyCons.map(distributeInnerVars);
|
||||||
|
TypeUnify unify = new TypeUnify();
|
||||||
|
Set<PlaceholderType> varianceTPHold;
|
||||||
|
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||||
|
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
||||||
|
|
||||||
|
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
||||||
|
|
||||||
|
if (resultmodel) {
|
||||||
|
/* UnifyResultModel Anfang */
|
||||||
|
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||||
|
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
||||||
|
urm.addUnifyResultListener(li);
|
||||||
|
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
||||||
|
generateBytecode(sf, li.getResults());
|
||||||
|
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||||
|
}
|
||||||
|
/* UnifyResultModel End */
|
||||||
|
else {
|
||||||
|
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
}
|
||||||
|
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()));
|
||||||
|
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
||||||
*
|
*
|
||||||
@@ -778,11 +723,12 @@ public class JavaTXCompiler {
|
|||||||
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
var codegen = new Codegen(converter.convert(clazz), this, converter);
|
||||||
var code = codegen.generate();
|
var code = codegen.generate();
|
||||||
generatedClasses.put(clazz.getClassName(), code);
|
generatedClasses.put(clazz.getClassName(), code);
|
||||||
converter.auxiliaries.forEach((name, source) -> {
|
|
||||||
generatedClasses.put(new JavaClassName(name), source);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
generatedGenerics.put(sf, converter.javaGenerics());
|
generatedGenerics.put(sf, converter.javaGenerics());
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
converter.auxiliaries.forEach((name, source) -> {
|
||||||
|
generatedClasses.put(new JavaClassName(name), source);
|
||||||
|
});
|
||||||
return generatedClasses;
|
return generatedClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package de.dhbwstuttgart.environment;
|
|
||||||
|
|
||||||
public class ByteArrayClassLoader extends ClassLoader implements IByteArrayClassLoader {
|
|
||||||
@Override
|
|
||||||
public Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError {
|
|
||||||
return defineClass(name, code, i, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> findClass(String name) throws ClassNotFoundException {
|
|
||||||
return super.findClass(name);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -30,11 +30,11 @@ public class CompilationEnvironment {
|
|||||||
public final PackageCrawler packageCrawler;
|
public final PackageCrawler packageCrawler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
|
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library
|
||||||
*
|
*
|
||||||
* @param sourceFiles die zu kompilierenden Dateien
|
* @param sourceFiles die zu kompilierenden Dateien
|
||||||
*/
|
*/
|
||||||
public CompilationEnvironment(List<File> sourceFiles) {
|
public CompilationEnvironment(List<File> sourceFiles, DirectoryClassLoader classLoader) {
|
||||||
/**
|
/**
|
||||||
* 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
|
* 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
|
||||||
*
|
*
|
||||||
@@ -54,7 +54,7 @@ public class CompilationEnvironment {
|
|||||||
// librarys = Arrays.asList(loader.getURLs());
|
// librarys = Arrays.asList(loader.getURLs());
|
||||||
|
|
||||||
this.sourceFiles = sourceFiles;
|
this.sourceFiles = sourceFiles;
|
||||||
this.packageCrawler = new PackageCrawler(librarys);
|
this.packageCrawler = new PackageCrawler(classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
|
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
|
||||||
@@ -104,12 +104,4 @@ public class CompilationEnvironment {
|
|||||||
return packageName;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,31 +5,61 @@ import java.io.IOException;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.*;
|
||||||
import java.nio.file.Path;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class DirectoryClassLoader extends URLClassLoader implements IByteArrayClassLoader {
|
public class DirectoryClassLoader extends URLClassLoader implements IByteArrayClassLoader {
|
||||||
public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
|
// public DirectoryClassLoader(File directory, java.lang.ClassLoader parent) {
|
||||||
super(generateURLArray(dirToURL(directory)), parent);
|
// super(generateURLArray(dirToURL(directory)), parent);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
|
public DirectoryClassLoader(List<File> directory, java.lang.ClassLoader parent) {
|
||||||
super(directory.stream().map(DirectoryClassLoader::dirToURL).collect(Collectors.toList()).toArray(new URL[0]), parent);
|
super(directory.stream().map(DirectoryClassLoader::dirToURL).flatMap(List::stream).collect(Collectors.toList()).toArray(new URL[0]), parent.getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URL[] generateURLArray(URL url) {
|
private static URL[] generateURLArray(URL url) {
|
||||||
return new URL[]{url};
|
return new URL[]{url};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URL dirToURL(File url){
|
private static List<URL> dirToURL(File file) {
|
||||||
if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
|
//if(!url.isDirectory())throw new RuntimeException(url.toString() + " is not a directory");
|
||||||
try {
|
|
||||||
return url.toURI().toURL();
|
Path dir;
|
||||||
} catch (MalformedURLException e) {
|
if (file.isDirectory()) {
|
||||||
throw new RuntimeException(e);
|
try {
|
||||||
|
return List.of(file.toURI().toURL()); // if file is a directory, use it as is
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dir = file.toPath().getParent(); // if file is not a directory, get its parent directory
|
||||||
|
String pattern = file.toPath().getFileName().toString(); // use the file name as a glob pattern
|
||||||
|
|
||||||
|
List<URL> urls = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
urls = Files.walk(dir)
|
||||||
|
.filter(Files::isRegularFile) // only consider files (not directories)
|
||||||
|
.filter(path -> {
|
||||||
|
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
|
||||||
|
return matcher.matches(path.getFileName()); // match the file name against the pattern
|
||||||
|
})
|
||||||
|
.map(path -> {
|
||||||
|
try {
|
||||||
|
return path.toUri().toURL();
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}) // convert the path to a URL
|
||||||
|
.toList(); // print the path of each matching file
|
||||||
|
} catch (IOException | RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -6,18 +6,22 @@ import java.nio.file.Path;
|
|||||||
|
|
||||||
public interface IByteArrayClassLoader {
|
public interface IByteArrayClassLoader {
|
||||||
|
|
||||||
Class loadClass(String path) throws ClassNotFoundException;
|
Class<?> loadClass(String path) throws ClassNotFoundException;
|
||||||
|
|
||||||
default Class loadClass(byte[] code) {
|
default Class<?> loadClass(byte[] code) {
|
||||||
return this._defineClass(null, code, 0, code.length);
|
return this.loadClass(null, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
default Class loadClass(Path path) throws IOException {
|
default Class<?> loadClass(String name, byte[] code) {
|
||||||
|
return this._defineClass(name, code, 0, code.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Class<?> loadClass(Path path) throws IOException {
|
||||||
var code = Files.readAllBytes(path);
|
var code = Files.readAllBytes(path);
|
||||||
return this._defineClass(null, code, 0, code.length);
|
return this._defineClass(null, code, 0, code.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?> findClass(String name) throws ClassNotFoundException;
|
public Class<?> findClass(String name) throws ClassNotFoundException;
|
||||||
|
|
||||||
Class _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
Class<?> _defineClass(String name, byte[] code, int i, int length) throws ClassFormatError;
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,10 @@
|
|||||||
package de.dhbwstuttgart.environment;
|
package de.dhbwstuttgart.environment;
|
||||||
|
|
||||||
import java.net.URL;
|
import io.github.classgraph.ClassGraph;
|
||||||
|
import io.github.classgraph.ScanResult;
|
||||||
|
|
||||||
import java.util.*;
|
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
|
* Hilft beim Durchsuchen von Packages
|
||||||
* Benutzt die Reflections-Library (https://github.com/ronmamo/reflections)
|
* Benutzt die Reflections-Library (https://github.com/ronmamo/reflections)
|
||||||
@@ -19,48 +12,30 @@ import org.reflections.vfs.SystemDir;
|
|||||||
*/
|
*/
|
||||||
public class PackageCrawler {
|
public class PackageCrawler {
|
||||||
|
|
||||||
final URL[] urls;
|
final DirectoryClassLoader classLoader;
|
||||||
public PackageCrawler(List<URL> urlList) {
|
public PackageCrawler(DirectoryClassLoader classLoader) {
|
||||||
urls = urlList.toArray(new URL[0]);
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Class<?>> getClassesInPackage(String packageName){
|
public Set<Class<?>> getClassesInPackage(String packageName) {
|
||||||
/*
|
var res = new HashSet<Class<?>>();
|
||||||
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);
|
try (ScanResult result = new ClassGraph()
|
||||||
|
.enableClassInfo()
|
||||||
|
.enableSystemJarsAndModules()
|
||||||
|
.addClassLoader(classLoader)
|
||||||
|
.acceptPackages(packageName)
|
||||||
|
.scan()) {
|
||||||
|
|
||||||
return classes;
|
for (var info : result.getAllClasses()) {
|
||||||
}
|
try {
|
||||||
|
var clazz = Class.forName(info.getName());
|
||||||
|
res.add(clazz);
|
||||||
|
} catch (ClassNotFoundException ignored) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public Set<Class<?>> getAllAvailableClasses(){
|
return res;
|
||||||
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){
|
public Map<String, Integer> getClassNames(String packageName){
|
||||||
|
@@ -0,0 +1,279 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
|
||||||
|
*/
|
||||||
|
public class LanguageServerInterface {
|
||||||
|
|
||||||
|
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||||
|
NameGenerator.resetTo(resetNamesTo);
|
||||||
|
return getResultSetAndAbstractSyntax(path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||||
|
NameGenerator.resetTo(resetNamesTo);
|
||||||
|
return getAST(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the ResultSets, GenericResultSet and the AST
|
||||||
|
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param path the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
//
|
||||||
|
// System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// URI uri = new URI(path);
|
||||||
|
// ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
||||||
|
// pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
||||||
|
// String stringPathWithoutName = "";
|
||||||
|
//
|
||||||
|
// for (String i : pathWithoutName) {
|
||||||
|
// stringPathWithoutName += "/" + i;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
||||||
|
// } catch (Exception e) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// try {
|
||||||
|
// (new File(stringPathWithoutName + "/out")).mkdirs();
|
||||||
|
// } catch (Exception e) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// var test = getLanguageServerTransferObject(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new ByteArrayClassLoader(), new File(stringPathWithoutName).getPath());
|
||||||
|
// System.setOut(System.out);
|
||||||
|
// return test;
|
||||||
|
// File oldTempSourcefile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".tmp"));
|
||||||
|
// File oldTempOutFile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".class"));
|
||||||
|
// Files.deleteIfExists(oldTempSourcefile.toPath());
|
||||||
|
// Files.deleteIfExists(oldTempOutFile.toPath());
|
||||||
|
// FileUtils.deleteDirectory(oldTempSourcefile);
|
||||||
|
//
|
||||||
|
// File tempSourcefile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".tmp"));
|
||||||
|
// File tempOutFile = new File(stringPathWithoutName + "/out/");
|
||||||
|
// FileUtils.writeStringToFile(tempSourcefile, input, "UTF-8");
|
||||||
|
//
|
||||||
|
// //TODO: Enable for multiple Class-Files
|
||||||
|
// JavaTXCompiler tx = new JavaTXCompiler(new ArrayList<File>(List.of(tempSourcefile)), new ArrayList<File>(List.of((tempSourcefile))), tempOutFile);
|
||||||
|
// var result = tx.getResultSetAndAbstractSyntax(tempSourcefile);
|
||||||
|
// System.setOut(System.out);
|
||||||
|
// tempSourcefile.delete();
|
||||||
|
// tempOutFile.delete();
|
||||||
|
// return result;
|
||||||
|
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the AST without calculating the result
|
||||||
|
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param path the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
|
||||||
|
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
|
||||||
|
|
||||||
|
URI uri = new URI(path);
|
||||||
|
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
||||||
|
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
||||||
|
String stringPathWithoutName = "";
|
||||||
|
|
||||||
|
for (String i : pathWithoutName) {
|
||||||
|
stringPathWithoutName += "/" + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
(new File(stringPathWithoutName + "/out")).mkdirs();
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
|
||||||
|
System.setOut(System.out);
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeClassFile(String name, byte[] code, Path outputPath) throws IOException {
|
||||||
|
Files.createDirectories(outputPath);
|
||||||
|
Files.write(outputPath.resolve(name + ".class"), code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, Path path, Path outputPath, String... files) throws IOException, ClassNotFoundException {
|
||||||
|
Files.createDirectories(outputPath);
|
||||||
|
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
|
||||||
|
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()), outputPath.toFile());
|
||||||
|
|
||||||
|
var result = new HashMap<String, Class<?>>();
|
||||||
|
for (var file : filenames) {
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
|
result.putAll(classes.stream().map(cli -> {
|
||||||
|
try {
|
||||||
|
return generateClass(converter.convert(cli), classLoader, converter, outputPath);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toMap(Class::getName, Function.identity())));
|
||||||
|
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
for (var entry : converter.auxiliaries.entrySet()) {
|
||||||
|
writeClassFile(entry.getKey(), entry.getValue(), outputPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry : compiler.loadedClasses.entrySet()) {
|
||||||
|
var name = entry.getKey().toString();
|
||||||
|
result.put(name, classLoader.loadClass(Path.of(entry.getValue().classFile().toURI())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, ASTToTargetAST converter, Path outputPath) throws IOException {
|
||||||
|
Codegen codegen = new Codegen(clazz, converter.compiler, converter);
|
||||||
|
var code = codegen.generate();
|
||||||
|
writeClassFile(clazz.qualifiedName().getClassName(), code, outputPath);
|
||||||
|
return classLoader.loadClass(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, ? extends Class<?>> generateClassFiles(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
|
var result = classes.stream().map(cli -> {
|
||||||
|
try {
|
||||||
|
return generateClass(converter.convert(cli), classLoader, converter, Path.of(filePath + "/out/"));
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toMap(Class::getName, Function.identity()));
|
||||||
|
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
for (var entry : converter.auxiliaries.entrySet()) {
|
||||||
|
writeClassFile(entry.getKey(), entry.getValue(), Path.of(filePath + "/out/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
return compiler.sourceFiles.get(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LanguageServerTransferObject getLanguageServerTransferObject(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(filePath, filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
|
var resultSet = compiler.typeInference(file);
|
||||||
|
|
||||||
|
var sourceFile = compiler.sourceFiles.get(file);
|
||||||
|
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
|
var ta = converter.javaGenerics();
|
||||||
|
var tb = converter.txGenerics();
|
||||||
|
Map<SourceFile, List<GenericsResult>> generics = new HashMap<>();
|
||||||
|
|
||||||
|
ArrayList<GenericsResult> genericsResults = new ArrayList<>();
|
||||||
|
genericsResults.addAll(ta);
|
||||||
|
genericsResults.addAll(tb);
|
||||||
|
generics.put(converter.compiler.sourceFiles.values().stream().findFirst().get(), ta);
|
||||||
|
var test = new LanguageServerTransferObject(resultSet, converter.compiler.sourceFiles.values().stream().findFirst().get(), "", compiler.getGeneratedGenerics());
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generates Bytecode for the given Path of the File.
|
||||||
|
* The Generated Bytecode can be found in the same place as the path, except the File lies in an /out/ Directory
|
||||||
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
|
*
|
||||||
|
* @param uri the URI of the File. See Example.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws URISyntaxException
|
||||||
|
*/
|
||||||
|
public void generateBytecode(URI uri) throws IOException, ClassNotFoundException, URISyntaxException {
|
||||||
|
|
||||||
|
// System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// File inputDir = new File(uri.getPath());
|
||||||
|
// File outFile = new File(uri.getPath() + "/out");
|
||||||
|
// FileUtils.cleanDirectory(outFile);
|
||||||
|
// String[] allowedEndings = {".jav"};
|
||||||
|
// ArrayList<File> files = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// try (Stream<Path> stream = Files.walk(Paths.get(inputDir.toURI()))) {
|
||||||
|
// stream.filter(Files::isRegularFile)
|
||||||
|
// .forEach(el -> files.add(el.toFile()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<String> javFiles = files.stream().filter(el -> el.getName().split("\\.").length >= 2 && el.getName().split("\\.")[el.getName().split("\\.").length - 1].contains("jav")).map(el -> el.getPath().replace(inputDir.getPath(), "").substring(1)).toList();
|
||||||
|
// //TODO: Link between Files
|
||||||
|
// generateClassFiles(new ByteArrayClassLoader(), Path.of(inputDir.toURI()), Path.of(outFile.toURI()), javFiles.toArray(new String[0]));
|
||||||
|
// System.setOut(System.out);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
|
||||||
|
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
|
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTree;
|
||||||
|
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ParserInterface {
|
||||||
|
|
||||||
|
public List<ParserError> getParseErrors(String input){
|
||||||
|
|
||||||
|
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
|
||||||
|
CharStream charStream = CharStreams.fromString(input);
|
||||||
|
|
||||||
|
Java17Lexer lexer = new Java17Lexer(charStream);
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
|
||||||
|
Java17Parser parser = new Java17Parser(tokens);
|
||||||
|
parser.removeErrorListeners();
|
||||||
|
parser.addErrorListener(errorListener);
|
||||||
|
|
||||||
|
|
||||||
|
ParseTree tree = parser.sourceFile();
|
||||||
|
ParseTreeWalker walker = new ParseTreeWalker();
|
||||||
|
Java17ParserBaseListener listener = new Java17ParserBaseListener();
|
||||||
|
walker.walk(listener, tree);
|
||||||
|
|
||||||
|
return errorListener.getErrorMessages();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.*;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CustomParserErrorHandler implements ANTLRErrorListener {
|
||||||
|
private final List<ParserError> errorMessages = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||||
|
int endCharPosition = charPositionInLine;
|
||||||
|
if (offendingSymbol instanceof Token) {
|
||||||
|
Token offendingToken = (Token) offendingSymbol;
|
||||||
|
endCharPosition = charPositionInLine + offendingToken.getText().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
|
||||||
|
errorMessages.add(parserError);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ParserError> getErrorMessages() {
|
||||||
|
return errorMessages;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,31 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LanguageServerTransferObject {
|
||||||
|
List<ResultSet> resultSets;
|
||||||
|
SourceFile Ast;
|
||||||
|
String printedAst;
|
||||||
|
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
|
||||||
|
this.resultSets = resultSets;
|
||||||
|
this.Ast = Ast;
|
||||||
|
this.printedAst = printedAst;
|
||||||
|
this.generatedGenerics = generatedGenerics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ResultSet> getResultSets() {return resultSets;}
|
||||||
|
public SourceFile getAst() {return Ast;}
|
||||||
|
public String getPrintedAst() {return printedAst;}
|
||||||
|
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
||||||
|
}
|
@@ -0,0 +1,48 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
public class ParserError {
|
||||||
|
|
||||||
|
private int line;
|
||||||
|
private int charPositionInLine;
|
||||||
|
private int endCharPosition;
|
||||||
|
String msg;
|
||||||
|
|
||||||
|
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
|
||||||
|
this.line = line;
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
this. endCharPosition = endCharPosition;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndCharPosition() {
|
||||||
|
return endCharPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndCharPosition(int endCharPosition) {
|
||||||
|
this.endCharPosition = endCharPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharPositionInLine(int charPositionInLine) {
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLine(int line) {
|
||||||
|
this.line = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCharPositionInLine() {
|
||||||
|
return charPositionInLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLine() {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,20 @@
|
|||||||
|
package de.dhbwstuttgart.languageServerInterface.model;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.reflect.TypeResolver;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
||||||
|
|
||||||
|
public class ResultSetListener implements UnifyResultListener {
|
||||||
|
|
||||||
|
TypeResolver typeResolver;
|
||||||
|
|
||||||
|
public ResultSetListener(TypeResolver typeResolver){
|
||||||
|
this.typeResolver = typeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewTypeResultFound(UnifyResultEvent evt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -158,7 +158,8 @@ public class FCGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf der direkten Argumentebene.
|
||||||
|
* Hier sind keine Wildcards zulässig
|
||||||
*/
|
*/
|
||||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||||
|
|
||||||
@@ -172,7 +173,7 @@ public class FCGenerator {
|
|||||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||||
params.add(param.acceptTV(this));
|
params.add(param.acceptTV(new TypeExchangerInner(gtvs)));
|
||||||
}
|
}
|
||||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||||
return ret;
|
return ret;
|
||||||
@@ -201,4 +202,51 @@ public class FCGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus auf den Argumenten der Argumente.
|
||||||
|
* Hier sind Wildcards zulässig
|
||||||
|
*/
|
||||||
|
private static class TypeExchangerInner implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||||
|
|
||||||
|
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||||
|
|
||||||
|
TypeExchangerInner(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
|
||||||
|
this.gtvs = gtvs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||||
|
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||||
|
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||||
|
params.add(param.acceptTV(this));
|
||||||
|
}
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||||
|
return superWildcardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
|
||||||
|
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
|
return extendsWildcardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||||
|
if(! gtvs.containsKey(genericRefType.getParsedName()))
|
||||||
|
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||||
|
return gtvs.get(genericRefType.getParsedName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,8 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
|
|||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
|
import de.dhbwstuttgart.target.tree.expression.TargetUnaryOp;
|
||||||
|
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
@@ -101,7 +103,6 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import org.stringtemplate.v4.ST;
|
|
||||||
|
|
||||||
public class StatementGenerator {
|
public class StatementGenerator {
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ public class StatementGenerator {
|
|||||||
this.superClass = superType;
|
this.superClass = superType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
|
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext, boolean methodparameters) {
|
||||||
List<Pattern> ret = new ArrayList<>();
|
List<Pattern> ret = new ArrayList<>();
|
||||||
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
|
List<Java17Parser.FormalParameterContext> fps = new ArrayList<>();
|
||||||
if (Objects.isNull(formalParameterListContext))
|
if (Objects.isNull(formalParameterListContext))
|
||||||
@@ -147,10 +148,12 @@ public class StatementGenerator {
|
|||||||
if (fp.typeType() != null) {
|
if (fp.typeType() != null) {
|
||||||
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
type = TypeGenerator.convert(fp.typeType(), reg, generics);
|
||||||
} else {
|
} else {
|
||||||
type = TypePlaceholder.fresh(fp.getStart());
|
type = methodparameters?
|
||||||
|
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
||||||
|
: TypePlaceholder.fresh(fp.getStart());
|
||||||
}
|
}
|
||||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||||
localVars.put(paramName, type);
|
localVars.put(paramName, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ParameterList(ret, ret.get(0).getOffset());
|
return new ParameterList(ret, ret.get(0).getOffset());
|
||||||
@@ -439,6 +442,7 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Pattern convert(PatternContext pattern) {
|
private Pattern convert(PatternContext pattern) {
|
||||||
|
|
||||||
return switch (pattern) {
|
return switch (pattern) {
|
||||||
case PPatternContext pPattern -> {
|
case PPatternContext pPattern -> {
|
||||||
yield convert(pPattern.primaryPattern());
|
yield convert(pPattern.primaryPattern());
|
||||||
@@ -453,30 +457,36 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private FormalParameter convert(PrimaryPatternContext pPattern) {
|
private FormalParameter convert(PrimaryPatternContext pPattern) {
|
||||||
|
|
||||||
switch (pPattern) {
|
switch (pPattern) {
|
||||||
case TPatternContext tPattern:
|
case TPatternContext tPattern:
|
||||||
TypePatternContext typePattern = tPattern.typePattern();
|
TypePatternContext typePattern = tPattern.typePattern();
|
||||||
var text = typePattern.identifier().getText();
|
var text = typePattern.identifier().getText();
|
||||||
var type = TypeGenerator.convert(typePattern.typeType(), reg, generics);
|
var type = typePattern.typeType() == null ? TypePlaceholder.fresh(pPattern.getStart()) : TypeGenerator.convert(typePattern.typeType(), reg, generics);
|
||||||
localVars.put(text, type);
|
localVars.put(text, type);
|
||||||
return new FormalParameter(text, type, typePattern.getStart());
|
return new FormalParameter(text, type, typePattern.getStart());
|
||||||
case RPatternContext rPattern:
|
case RPatternContext rPattern:
|
||||||
RecordPatternContext recordPattern = rPattern.recordPattern();
|
RecordPatternContext recordPattern = rPattern.recordPattern();
|
||||||
return convert(recordPattern);
|
return convert(recordPattern);
|
||||||
default:
|
case Java17Parser.LPatternContext patternContext: return new LiteralPattern(TypePlaceholder.fresh(patternContext.start), convert(patternContext.literal().get(0)), patternContext.start);
|
||||||
throw new NotImplementedException();
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecordPattern convert(RecordPatternContext recordPatternCtx) {
|
private RecordPattern convert(RecordPatternContext recordPatternCtx) {
|
||||||
List<PatternContext> subPatternCtx = recordPatternCtx.recordStructurePattern().recordComponentPatternList().pattern();
|
var cpl = recordPatternCtx.recordStructurePattern().recordComponentPatternList();
|
||||||
|
List<PatternContext> subPatternCtx = cpl == null ? List.of() : cpl.pattern();
|
||||||
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
|
List<Pattern> subPattern = subPatternCtx.stream().map(this::convert).collect(Collectors.toList());
|
||||||
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
IdentifierContext identifierCtx = recordPatternCtx.identifier();
|
||||||
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
var text = (identifierCtx != null) ? identifierCtx.getText() : null;
|
||||||
var type = TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
|
//Hier evtl. Typ anpassen -> wenn kein Typ bekannt ist push neuen Typ auf Hashtable
|
||||||
|
var type = recordPatternCtx.typeType() == null ? TypePlaceholder.fresh(recordPatternCtx.getStart()) : TypeGenerator.convert(recordPatternCtx.typeType(), reg, generics);
|
||||||
if (text != null) localVars.put(text, type);
|
if (text != null) localVars.put(text, type);
|
||||||
return new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
|
var ret = new RecordPattern(subPattern, text, type, recordPatternCtx.getStart());
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.WhileloopContext stmt) {
|
private Statement convert(Java17Parser.WhileloopContext stmt) {
|
||||||
@@ -583,7 +593,7 @@ public class StatementGenerator {
|
|||||||
initValue = convert(varDecl.variableInitializer().expression());
|
initValue = convert(varDecl.variableInitializer().expression());
|
||||||
}
|
}
|
||||||
var fieldEntry = fields.get(name.getText());
|
var fieldEntry = fields.get(name.getText());
|
||||||
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.BreakstmtContext stmt) {
|
private Statement convert(Java17Parser.BreakstmtContext stmt) {
|
||||||
@@ -597,8 +607,12 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
||||||
// TODO
|
Token offset = stmt.getStart();
|
||||||
throw new NotImplementedException();
|
if (!Objects.isNull(stmt.identifier())) {
|
||||||
|
return new Continue(localVars.get(stmt.identifier().getText()), offset);
|
||||||
|
} else {
|
||||||
|
return new Continue(TypePlaceholder.fresh(offset), offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.SemistmtContext stmt) {
|
private Statement convert(Java17Parser.SemistmtContext stmt) {
|
||||||
@@ -693,7 +707,7 @@ public class StatementGenerator {
|
|||||||
if (!Objects.isNull(expr.methodCall())) {
|
if (!Objects.isNull(expr.methodCall())) {
|
||||||
return convert(expr.methodCall(), expr.expression(), offset);
|
return convert(expr.methodCall(), expr.expression(), offset);
|
||||||
} else if (!Objects.isNull(expr.identifier())) {
|
} else if (!Objects.isNull(expr.identifier())) {
|
||||||
return generateLocalOrFieldVarOrClassName(expr.getText(), offset);
|
return new FieldVar(convert(expr.expression()), expr.identifier().getText(), TypePlaceholder.fresh(expr.identifier().start), offset);
|
||||||
} else {
|
} else {
|
||||||
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
// Für alle anderen Optionen, wie Feldzugriff, Aufrufe von super oder explizite
|
||||||
// generische Invokationen
|
// generische Invokationen
|
||||||
@@ -769,62 +783,25 @@ public class StatementGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
|
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
|
||||||
*
|
*
|
||||||
* @param expression
|
* @param expression
|
||||||
* @param offset
|
* @param offset
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
private Expression generateLocalOrFieldVarOrClassName(String expression, Token offset) {
|
||||||
String[] parts = expression.split("\\.");
|
// Check for localVar:
|
||||||
if (parts.length < 2) {
|
if (localVars.get(expression) != null) {
|
||||||
// Check for localVar:
|
return new LocalVar(expression, localVars.get(expression), offset);
|
||||||
if (localVars.get(expression) != null) {
|
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||||
return new LocalVar(expression, localVars.get(expression), offset);
|
// gleiche TPH bekommen
|
||||||
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
return new FieldVar(new This(offset), expression, fields.get(expression).type(), offset);
|
||||||
// gleiche TPH bekommen
|
} else if (reg.contains(expression)) {
|
||||||
var field = fields.get(expression);
|
return generateStaticClassName(expression, offset);
|
||||||
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
|
|
||||||
} else if (reg.contains(expression)) {
|
|
||||||
return generateStaticClassName(expression, offset);
|
|
||||||
} else {
|
|
||||||
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
|
||||||
localVars.put(expression, TypePlaceholder.fresh(offset));
|
|
||||||
return new LocalVar(expression, localVars.get(expression), offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return generateFieldVarOrClassname(expression, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Expression generateFieldVarOrClassname(String expression, Token offset) {
|
|
||||||
String[] parts = expression.split("\\.");
|
|
||||||
String whole = "";
|
|
||||||
Expression receiver = null;
|
|
||||||
for (String part : parts) {
|
|
||||||
whole += part;
|
|
||||||
// Check for Classname:
|
|
||||||
if (reg.contains(whole)) {
|
|
||||||
receiver = generateStaticClassName(whole, offset);
|
|
||||||
}
|
|
||||||
whole += ".";
|
|
||||||
}
|
|
||||||
var fieldName = parts[parts.length - 1];
|
|
||||||
|
|
||||||
var isStatic = false;
|
|
||||||
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
|
||||||
receiver = new This(offset);
|
|
||||||
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
|
||||||
} else if (parts[0].contentEquals("super")) {
|
|
||||||
receiver = new Super(TypePlaceholder.fresh(offset), offset);
|
|
||||||
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
|
||||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
|
||||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
|
||||||
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
|
||||||
} else {
|
} else {
|
||||||
StaticClassName cname = (StaticClassName) receiver;
|
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
||||||
var javaClassName = reg.getName(cname.getType().toString());
|
localVars.put(expression, TypePlaceholder.fresh(offset));
|
||||||
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
|
return new LocalVar(expression, localVars.get(expression), offset);
|
||||||
}
|
}
|
||||||
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
||||||
@@ -860,10 +837,8 @@ public class StatementGenerator {
|
|||||||
private Statement convert(AssignexpressionContext expr) {
|
private Statement convert(AssignexpressionContext expr) {
|
||||||
switch (expr.bop.getText()) {
|
switch (expr.bop.getText()) {
|
||||||
case "=":
|
case "=":
|
||||||
ExpressionContext leftside = expr.expression(0);
|
AssignLeftSide leftHandSide = convertAssignLHS(convert(expr.expression(0)));
|
||||||
AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart());
|
return new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
|
||||||
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
|
|
||||||
return ret;
|
|
||||||
case "+=":
|
case "+=":
|
||||||
case "-=":
|
case "-=":
|
||||||
case "*=":
|
case "*=":
|
||||||
@@ -880,8 +855,8 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AssignLeftSide convert(String leftHandSide, Token start) {
|
private AssignLeftSide convertAssignLHS(Expression expr) {
|
||||||
Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide, start);
|
Expression leftSide = expr;
|
||||||
if (leftSide instanceof FieldVar)
|
if (leftSide instanceof FieldVar)
|
||||||
return new AssignToField((FieldVar) leftSide);
|
return new AssignToField((FieldVar) leftSide);
|
||||||
else if (leftSide instanceof LocalVar)
|
else if (leftSide instanceof LocalVar)
|
||||||
@@ -1094,7 +1069,7 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||||
} else if (lambdaParams.formalParameterList() != null) {
|
} else if (lambdaParams.formalParameterList() != null) {
|
||||||
params = convert(lambdaParams.formalParameterList());
|
params = convert(lambdaParams.formalParameterList(), false);
|
||||||
// }else if( lambdaParams.inferredFormalParameterList != null){
|
// }else if( lambdaParams.inferredFormalParameterList != null){
|
||||||
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
|
} else if (!Objects.isNull(lambdaParams.lambdaLVTIList())) {
|
||||||
List<Pattern> parameterList = new ArrayList<>();
|
List<Pattern> parameterList = new ArrayList<>();
|
||||||
@@ -1124,9 +1099,9 @@ public class StatementGenerator {
|
|||||||
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);
|
||||||
}
|
}
|
||||||
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
|
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
|
||||||
funNParams.add(TypePlaceholder.fresh(expression.getStart()));// ret-Type
|
funNParams.add(TypePlaceholder.fresh(expression.getStart(), -1, false));// ret-Type
|
||||||
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
|
params.getFormalparalist().forEach(formalParameter -> // Für jeden Parameter einen TPH anfügen:
|
||||||
funNParams.add(TypePlaceholder.fresh(expression.getStart())));
|
funNParams.add(TypePlaceholder.fresh(expression.getStart(), 1, false)));
|
||||||
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
RefTypeOrTPHOrWildcardOrGeneric lambdaType = TypePlaceholder.fresh(expression.getStart());
|
||||||
// RefType lambdaType = new
|
// RefType lambdaType = new
|
||||||
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
// RefType(reg.getName("Fun"+params.getFormalparalist().size()),
|
||||||
|
@@ -71,10 +71,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
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 {
|
public class SyntaxTreeGenerator {
|
||||||
private JavaClassRegistry reg;
|
private JavaClassRegistry reg;
|
||||||
@@ -258,7 +254,10 @@ public class SyntaxTreeGenerator {
|
|||||||
List<RefType> implementedInterfaces = new ArrayList<>();
|
List<RefType> implementedInterfaces = new ArrayList<>();
|
||||||
List<Pattern> constructorParameters = new ArrayList<>();
|
List<Pattern> constructorParameters = new ArrayList<>();
|
||||||
List<Statement> constructorStatements = new ArrayList<>();
|
List<Statement> constructorStatements = new ArrayList<>();
|
||||||
for (RecordComponentContext component : recordDeclaration.recordHeader().recordComponentList().recordComponent()) {
|
|
||||||
|
List<Java17Parser.RecordComponentContext> components = recordDeclaration.recordHeader().recordComponentList() != null ?
|
||||||
|
recordDeclaration.recordHeader().recordComponentList().recordComponent(): List.of();
|
||||||
|
for (RecordComponentContext component : components) {
|
||||||
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
int fieldmodifiers = allmodifiers.get("private") + allmodifiers.get("final");
|
||||||
String fieldname = component.identifier().getText();
|
String fieldname = component.identifier().getText();
|
||||||
Token fieldoffset = component.getStart();
|
Token fieldoffset = component.getStart();
|
||||||
@@ -270,7 +269,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
||||||
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
||||||
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
|
FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
|
||||||
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
||||||
Statement returnStatement = new Return(fieldvar, offset);
|
Statement returnStatement = new Return(fieldvar, offset);
|
||||||
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
||||||
@@ -394,12 +393,12 @@ public class SyntaxTreeGenerator {
|
|||||||
if (!Objects.isNull(ctx.EXTENDS())) {
|
if (!Objects.isNull(ctx.EXTENDS())) {
|
||||||
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
|
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
|
||||||
}
|
}
|
||||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
List<RefType> permittedSubtypes = null;
|
||||||
// Ist Bit für 'sealed'-Modifier gesetzt
|
// Ist Bit für 'sealed'-Modifier gesetzt
|
||||||
if ((modifiers & 4096) != 0) {
|
if ((modifiers & 4096) != 0) {
|
||||||
if (!Objects.isNull(ctx.PERMITS())) {
|
if (!Objects.isNull(ctx.PERMITS())) {
|
||||||
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
|
||||||
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
|
||||||
} else {
|
} else {
|
||||||
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
// falls sealed modifier ohne 'permits'-List oder umgekehrt
|
||||||
throw new NotImplementedException("Invalid sealed class declaration");
|
throw new NotImplementedException("Invalid sealed class declaration");
|
||||||
@@ -436,7 +435,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList(), true);
|
||||||
MethodBodyContext body = bodydeclaration.methodBody();
|
MethodBodyContext body = bodydeclaration.methodBody();
|
||||||
Block block = null;
|
Block block = null;
|
||||||
if (!(body instanceof EmptymethodContext)) {
|
if (!(body instanceof EmptymethodContext)) {
|
||||||
@@ -533,7 +532,7 @@ public class SyntaxTreeGenerator {
|
|||||||
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric retType;
|
RefTypeOrTPHOrWildcardOrGeneric retType;
|
||||||
if (Objects.isNull(header.refType())) {
|
if (Objects.isNull(header.refType())) {
|
||||||
retType = TypePlaceholder.fresh(header.getStart());
|
retType = TypePlaceholder.fresh(header.getStart(), -1, false);
|
||||||
} else {
|
} else {
|
||||||
if (header.refType() instanceof RefType2Context reftype) {
|
if (header.refType() instanceof RefType2Context reftype) {
|
||||||
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
|
retType = TypeGenerator.convert(reftype.typeType(), reg, generics);
|
||||||
@@ -542,7 +541,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList(), true);
|
||||||
MethodBodyContext body = methoddeclaration.methodBody();
|
MethodBodyContext body = methoddeclaration.methodBody();
|
||||||
Block block = null;
|
Block block = null;
|
||||||
if (body instanceof EmptymethodContext emptymethod) {
|
if (body instanceof EmptymethodContext emptymethod) {
|
||||||
@@ -582,7 +581,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
||||||
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList(), true);
|
||||||
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
|
Block block = prepareBlock(stmtgen.convert(constructordeclaration.constructorBody, true), superClass);
|
||||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
||||||
}
|
}
|
||||||
@@ -595,7 +594,7 @@ public class SyntaxTreeGenerator {
|
|||||||
} else {
|
} else {
|
||||||
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
|
// PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
|
||||||
// Modifier zu bekommen
|
// Modifier zu bekommen
|
||||||
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
|
fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart(), -1, false);
|
||||||
}
|
}
|
||||||
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
||||||
String fieldName = varDecl.variableDeclaratorId().getText();
|
String fieldName = varDecl.variableDeclaratorId().getText();
|
||||||
|
@@ -41,7 +41,7 @@ public class JavaClassName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt von einem Klassennamen nur den Namen der Klasse zur<EFBFBD>ck
|
* Gibt von einem Klassennamen nur den Namen der Klasse zurück
|
||||||
* Beispiel:
|
* Beispiel:
|
||||||
* java.lang.Object wird zu: Object
|
* java.lang.Object wird zu: Object
|
||||||
*/
|
*/
|
||||||
|
@@ -5,9 +5,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
|
* Speichert die Klassen für einen bestimmten Projektscope
|
||||||
*/
|
*/
|
||||||
public class JavaClassRegistry {
|
public class JavaClassRegistry{
|
||||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||||
|
|
||||||
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
||||||
@@ -22,6 +22,10 @@ public class JavaClassRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<JavaClassName> getAllClassNames(){
|
||||||
|
return existingClasses.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
public void addName(String className, int numberOfGenerics) {
|
public void addName(String className, int numberOfGenerics) {
|
||||||
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,8 @@ public interface ASTVisitor extends StatementVisitor{
|
|||||||
|
|
||||||
void visit(FormalParameter formalParameter);
|
void visit(FormalParameter formalParameter);
|
||||||
|
|
||||||
|
void visit(LiteralPattern literalPattern);
|
||||||
|
|
||||||
void visit(GenericDeclarationList genericTypeVars);
|
void visit(GenericDeclarationList genericTypeVars);
|
||||||
|
|
||||||
void visit(Field field);
|
void visit(Field field);
|
||||||
|
@@ -37,6 +37,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
|||||||
formalParameter.getType().accept((ASTVisitor) this);
|
formalParameter.getType().accept((ASTVisitor) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LiteralPattern literalPattern) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GenericDeclarationList genericTypeVars) {
|
public void visit(GenericDeclarationList genericTypeVars) {
|
||||||
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
||||||
@@ -236,6 +241,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
|||||||
aBreak.accept(this);
|
aBreak.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
aContinue.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
|
@@ -86,6 +86,9 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
return staticInitializer;
|
return staticInitializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSealed() { return permittedSubtypes != null; }
|
||||||
|
public List<RefType> getPermittedSubtypes() { return permittedSubtypes != null ? permittedSubtypes : List.of(); }
|
||||||
|
|
||||||
public boolean isInterface() {
|
public boolean isInterface() {
|
||||||
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
||||||
}
|
}
|
||||||
@@ -188,9 +191,8 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (!(o instanceof ClassOrInterface other)) return false;
|
||||||
ClassOrInterface that = (ClassOrInterface) o;
|
return Objects.equals(name, other.name);
|
||||||
return Objects.equals(name, that.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
package de.dhbwstuttgart.syntaxtree;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Pattern;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||||
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
public class LiteralPattern extends FormalParameter
|
||||||
|
{
|
||||||
|
public final Expression value;
|
||||||
|
public LiteralPattern(RefTypeOrTPHOrWildcardOrGeneric type, Expression value, Token offset) {
|
||||||
|
super(null, type, offset);
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public FormalParameter withType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
return new LiteralPattern(type, value, getOffset());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void accept(ASTVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree;
|
|||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
|
|
||||||
|
|
||||||
public interface StatementVisitor {
|
public interface StatementVisitor {
|
||||||
|
|
||||||
void visit(ArgumentList argumentList);
|
void visit(ArgumentList argumentList);
|
||||||
@@ -53,6 +54,8 @@ public interface StatementVisitor {
|
|||||||
|
|
||||||
void visit(Break aBreak);
|
void visit(Break aBreak);
|
||||||
|
|
||||||
|
void visit(Continue aContinue);
|
||||||
|
|
||||||
void visit(Yield aYield);
|
void visit(Yield aYield);
|
||||||
|
|
||||||
void visit(StaticClassName staticClassName);
|
void visit(StaticClassName staticClassName);
|
||||||
|
@@ -176,8 +176,9 @@ public class ASTFactory {
|
|||||||
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
||||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||||
}
|
}
|
||||||
List<RefType> permittedSubtypes = new ArrayList<>();
|
List<RefType> permittedSubtypes = null;
|
||||||
if (jreClass.isSealed()) {
|
if (jreClass.isSealed()) {
|
||||||
|
permittedSubtypes = new ArrayList<>();
|
||||||
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
||||||
permittedSubtypes.add((RefType) createType(subclass));
|
permittedSubtypes.add((RefType) createType(subclass));
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,10 @@ public class NameGenerator {
|
|||||||
public static void reset() {
|
public static void reset() {
|
||||||
strNextName = "A";
|
strNextName = "A";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void resetTo(String name) {
|
||||||
|
strNextName = name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
||||||
|
@@ -129,9 +129,10 @@ public class UnifyTypeFactory {
|
|||||||
if (tph.getName().equals("AFR")) {
|
if (tph.getName().equals("AFR")) {
|
||||||
System.out.println("XXX"+innerType);
|
System.out.println("XXX"+innerType);
|
||||||
}
|
}
|
||||||
PlaceholderType ntph = new PlaceholderType(tph.getName());
|
PlaceholderType ntph = new PlaceholderType(tph.getName(), tph.getVariance());
|
||||||
ntph.setVariance(tph.getVariance());
|
ntph.setVariance(tph.getVariance());
|
||||||
ntph.setOrCons(tph.getOrCons());
|
ntph.setOrCons(tph.getOrCons());
|
||||||
|
ntph.setWildcardtable(tph.getWildcardtable());
|
||||||
int in = PLACEHOLDERS.indexOf(ntph);
|
int in = PLACEHOLDERS.indexOf(ntph);
|
||||||
if (in == -1) {
|
if (in == -1) {
|
||||||
PLACEHOLDERS.add(ntph);
|
PLACEHOLDERS.add(ntph);
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
package de.dhbwstuttgart.syntaxtree.statement;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
public class Continue extends Statement {
|
||||||
|
|
||||||
|
public Continue(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||||
|
super(type, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(StatementVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -17,13 +17,11 @@ public class FieldVar extends Expression {
|
|||||||
|
|
||||||
public final String fieldVarName;
|
public final String fieldVarName;
|
||||||
public final Expression receiver;
|
public final Expression receiver;
|
||||||
public final boolean isStatic;
|
|
||||||
|
|
||||||
public FieldVar(Expression receiver, boolean isStatic, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
public FieldVar(Expression receiver, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||||
super(type, offset);
|
super(type, offset);
|
||||||
this.fieldVarName = fieldVarName;
|
this.fieldVarName = fieldVarName;
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
this.isStatic = isStatic;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -8,6 +8,7 @@ import org.antlr.v4.runtime.Token;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||||
@@ -49,10 +50,7 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 0;
|
return this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
||||||
hash += super.hashCode();
|
|
||||||
hash += this.name.hashCode();//Nur den Name hashen. Sorgt für langsame, aber funktionierende HashMaps
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
public RefType(JavaClassName fullyQualifiedName, List<RefTypeOrTPHOrWildcardOrGeneric> parameter, Token offset) {
|
||||||
@@ -83,6 +81,7 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if(obj instanceof RefType){
|
if(obj instanceof RefType){
|
||||||
|
if (!Objects.equals(this.name, ((RefType) obj).name)) return false;
|
||||||
boolean ret = true;
|
boolean ret = true;
|
||||||
|
|
||||||
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
//if(!(super.equals(obj))) PL 2020-03-12 muss vll. einkommentiert werden
|
||||||
|
@@ -21,10 +21,18 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wird im Generate Generics Teil nach der Rueckumwandlung nach dem Unify genutzt
|
* variance shows the variance of the pair
|
||||||
*/
|
* 1: contravariant
|
||||||
|
* -1 covariant
|
||||||
|
* 0 invariant
|
||||||
|
*/
|
||||||
private int variance = 0;
|
private int variance = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isWildcardable gibt an, ob ein Wildcardtyp dem PlaceholderType zugeordnet werden darf
|
||||||
|
*/
|
||||||
|
private boolean wildcardable = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fuer Oder-Constraints:
|
* Fuer Oder-Constraints:
|
||||||
* orCons = 1: Receiver
|
* orCons = 1: Receiver
|
||||||
@@ -39,10 +47,12 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
* Factory-Methode <code>fresh()</code> erzeugt.
|
* Factory-Methode <code>fresh()</code> erzeugt.
|
||||||
* <br>Author: J�rg B�uerle
|
* <br>Author: J�rg B�uerle
|
||||||
*/
|
*/
|
||||||
private TypePlaceholder(String name, Token offset)
|
private TypePlaceholder(String name, Token offset, int variance, boolean wildcardable)
|
||||||
{
|
{
|
||||||
super(offset);
|
super(offset);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.variance = variance;
|
||||||
|
this.wildcardable = wildcardable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -53,11 +63,15 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static TypePlaceholder fresh(Token position){
|
public static TypePlaceholder fresh(Token position){
|
||||||
return new TypePlaceholder(NameGenerator.makeNewName(), position);
|
return new TypePlaceholder(NameGenerator.makeNewName(), position, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TypePlaceholder fresh(Token position, int variance, boolean wildcardable){
|
||||||
|
return new TypePlaceholder(NameGenerator.makeNewName(), position, variance, wildcardable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric of(String name) {
|
public static RefTypeOrTPHOrWildcardOrGeneric of(String name) {
|
||||||
return new TypePlaceholder(name, new NullToken());
|
return new TypePlaceholder(name, new NullToken(),0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -120,4 +134,9 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
public byte getOrCons() {
|
public byte getOrCons() {
|
||||||
return orCons;
|
return orCons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Boolean getWildcardtable() {
|
||||||
|
return wildcardable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,11 @@ public class OutputGenerator implements ASTVisitor {
|
|||||||
out.append(formalParameter.getName());
|
out.append(formalParameter.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LiteralPattern literalPattern) {
|
||||||
|
literalPattern.value.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GenericDeclarationList genericTypeVars) {
|
public void visit(GenericDeclarationList genericTypeVars) {
|
||||||
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
|
||||||
@@ -333,6 +338,11 @@ public class OutputGenerator implements ASTVisitor {
|
|||||||
out.append("break");
|
out.append("break");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
out.append("continue");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
@@ -503,12 +513,11 @@ public class OutputGenerator implements ASTVisitor {
|
|||||||
aRecordPattern.getType().accept(this);
|
aRecordPattern.getType().accept(this);
|
||||||
out.append("(");
|
out.append("(");
|
||||||
List<Pattern> subPatterns = aRecordPattern.getSubPattern();
|
List<Pattern> subPatterns = aRecordPattern.getSubPattern();
|
||||||
int i;
|
for (var i = 0; i < subPatterns.size(); i++) {
|
||||||
for (i = 0; i < subPatterns.size() - 1; i++) {
|
|
||||||
subPatterns.get(i).accept(this);
|
subPatterns.get(i).accept(this);
|
||||||
out.append(", ");
|
if (i < subPatterns.size() - 1)
|
||||||
|
out.append(", ");
|
||||||
}
|
}
|
||||||
subPatterns.get(i).accept(this);
|
|
||||||
String name;
|
String name;
|
||||||
if ((name = aRecordPattern.getName()) != null)
|
if ((name = aRecordPattern.getName()) != null)
|
||||||
out.append(name);
|
out.append(name);
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
@@ -12,31 +12,41 @@ import de.dhbwstuttgart.syntaxtree.Record;
|
|||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.visual.OutputGenerator;
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
|
|
||||||
import javax.sql.rowset.RowSetWarning;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author dholle
|
* @author dholle
|
||||||
*/
|
*/
|
||||||
public class ASTToTargetAST {
|
public class ASTToTargetAST {
|
||||||
|
|
||||||
|
record SignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {};
|
||||||
|
record SignaturePairTarget(TargetType signature, TargetType parameter) {}
|
||||||
|
|
||||||
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
||||||
|
|
||||||
protected List<Generics> all;
|
protected List<Generics> all;
|
||||||
public Generics generics;
|
public Generics generics;
|
||||||
|
public List<Generics> currentMethodOverloads;
|
||||||
|
|
||||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||||
|
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||||
|
private Method currentMethod;
|
||||||
|
|
||||||
public final JavaTXCompiler compiler;
|
public final JavaTXCompiler compiler;
|
||||||
|
|
||||||
|
public List<RefTypeOrTPHOrWildcardOrGeneric> findAllVariants(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
return javaGenerics().stream().map(generics -> generics.resolve(type)).distinct().toList();
|
||||||
|
}
|
||||||
|
|
||||||
public List<GenericsResult> txGenerics() {
|
public List<GenericsResult> txGenerics() {
|
||||||
return all.stream().map(generics -> new GenericsResult(generics.txGenerics)).toList();
|
return all.stream().map(generics -> new GenericsResult(generics.txGenerics)).toList();
|
||||||
}
|
}
|
||||||
@@ -55,14 +65,14 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected IByteArrayClassLoader classLoader;
|
public IByteArrayClassLoader classLoader;
|
||||||
protected SourceFile sourceFile;
|
protected SourceFile sourceFile;
|
||||||
|
|
||||||
public ASTToTargetAST(List<ResultSet> resultSets) {
|
public ASTToTargetAST(List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||||
this(null, resultSets);
|
this(null, resultSets, classLoader);
|
||||||
}
|
}
|
||||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets) {
|
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, IByteArrayClassLoader classLoader) {
|
||||||
this(compiler, resultSets, null, new ByteArrayClassLoader());
|
this(compiler, resultSets, null, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
public ASTToTargetAST(JavaTXCompiler compiler, List<ResultSet> resultSets, SourceFile sourceFile, IByteArrayClassLoader classLoader) {
|
||||||
@@ -77,6 +87,12 @@ public class ASTToTargetAST {
|
|||||||
this.generics = all.get(0);
|
this.generics = all.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
||||||
|
var set = tphsInMethods.getOrDefault(currentMethod, new HashSet<>());
|
||||||
|
set.add(new SignaturePair(signature, parameter));
|
||||||
|
tphsInMethods.put(currentMethod, set);
|
||||||
|
}
|
||||||
|
|
||||||
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
||||||
Optional<Method> method = Optional.empty();
|
Optional<Method> method = Optional.empty();
|
||||||
while (method.isEmpty()) {
|
while (method.isEmpty()) {
|
||||||
@@ -130,6 +146,207 @@ public class ASTToTargetAST {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This finds a common sealed interface type to group together methods that use different records
|
||||||
|
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
||||||
|
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
|
||||||
|
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
|
||||||
|
return List.of(compiler.getClass(new JavaClassName(ta.name())));
|
||||||
|
if (b instanceof TargetRefType tb && a instanceof TargetGenericType)
|
||||||
|
return List.of(compiler.getClass(new JavaClassName(tb.name())));
|
||||||
|
|
||||||
|
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
|
||||||
|
var res = new HashSet<ClassOrInterface>();
|
||||||
|
|
||||||
|
var cla = compiler.getClass(new JavaClassName(ta.name()));
|
||||||
|
var clb = compiler.getClass(new JavaClassName(tb.name()));
|
||||||
|
|
||||||
|
if (cla.equals(clb)) return List.of(cla);
|
||||||
|
|
||||||
|
while (!cla.equals(ASTFactory.createObjectClass())) {
|
||||||
|
var clb2 = clb;
|
||||||
|
while (!clb2.equals(ASTFactory.createObjectClass())) {
|
||||||
|
for (var intfa : cla.getSuperInterfaces()) {
|
||||||
|
for (var intfb : clb.getSuperInterfaces()) {
|
||||||
|
if (intfa.equals(intfb)) {
|
||||||
|
var clintf = compiler.getClass(intfa.getName());
|
||||||
|
if (clintf.isSealed()) {
|
||||||
|
res.add(clintf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clb2 = compiler.getClass(clb2.getSuperClass().getName());
|
||||||
|
}
|
||||||
|
cla = compiler.getClass(cla.getSuperClass().getName());
|
||||||
|
}
|
||||||
|
return res.stream().toList();
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO This is ugly and probably doesn't work right
|
||||||
|
private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
|
||||||
|
if (!a.name().equals(b.name())) return false;
|
||||||
|
if (a.subPatterns().size() != b.subPatterns().size()) return false;
|
||||||
|
for (var i = 0; i < a.subPatterns().size(); i++) {
|
||||||
|
var p1 = a.subPatterns().get(i);
|
||||||
|
var p2 = b.subPatterns().get(i);
|
||||||
|
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
||||||
|
patternStrictlyEquals(pc1, pc2)) return false;
|
||||||
|
if (p1 instanceof TargetTypePattern pt1 && p2 instanceof TargetTypePattern pt2) {
|
||||||
|
if (pt1.type() instanceof TargetGenericType && pt2.type() instanceof TargetGenericType) continue;
|
||||||
|
}
|
||||||
|
if (!p1.type().equals(p2.type()) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canCombine(TargetMethod m1, TargetMethod m2) {
|
||||||
|
if (!m1.name().equals(m2.name())) return false;
|
||||||
|
var s1 = m1.signature();
|
||||||
|
var s2 = m2.signature();
|
||||||
|
if (s1.parameters().size() != s2.parameters().size()) return false;
|
||||||
|
if (s1.parameters().isEmpty()) return false;
|
||||||
|
for (var i = 0; i < s1.parameters().size(); i++) {
|
||||||
|
var p1 = s1.parameters().get(i).pattern();
|
||||||
|
var p2 = s2.parameters().get(i).pattern();
|
||||||
|
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
|
||||||
|
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
||||||
|
patternStrictlyEquals(pc1, pc2)) return false;
|
||||||
|
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Combination(TargetMethod a, TargetMethod b) {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Combination(TargetMethod a1, TargetMethod b1))) return false;
|
||||||
|
return this.a.equals(a1) && this.b.equals(b1) ||
|
||||||
|
this.a.equals(b1) && this.b.equals(a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(a) + Objects.hashCode(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
||||||
|
var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
|
||||||
|
for (var generics : all) {
|
||||||
|
mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < methods.size(); i++) {
|
||||||
|
var method = methods.get(i);
|
||||||
|
// Convert all methods
|
||||||
|
var methodsWithTphs = convert(input, method);
|
||||||
|
for (var m : methodsWithTphs) {
|
||||||
|
var resultMethods = mapOfTargetMethods.get(m.generics);
|
||||||
|
resultMethods[i] = m.method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*System.out.println("============== INPUT ==============");
|
||||||
|
for (var m : mapOfTargetMethods.values()) {
|
||||||
|
for (var v : m) System.out.println(v.name() + " " + v.getSignature());
|
||||||
|
System.out.println();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
var allCombinations = new HashSet<Set<Combination>>();
|
||||||
|
// Combine methods based on their signature and position in the result set
|
||||||
|
for (var g1 : all) {
|
||||||
|
var resMeth1 = mapOfTargetMethods.get(g1);
|
||||||
|
for (var i = 0; i < methods.size(); i++) {
|
||||||
|
var m1 = resMeth1[i];
|
||||||
|
if (m1 == null) continue;
|
||||||
|
|
||||||
|
for (var g2 : all) {
|
||||||
|
if (g1 == g2) continue; // No need to combine the same method
|
||||||
|
var resMeth2 = mapOfTargetMethods.get(g2);
|
||||||
|
var m2 = resMeth2[i];
|
||||||
|
if (m2 == null) continue;
|
||||||
|
|
||||||
|
var combinations = new HashSet<Combination>();
|
||||||
|
|
||||||
|
if (canCombine(m1, m2)) {
|
||||||
|
//System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
|
||||||
|
combinations.add(new Combination(m1, m2));
|
||||||
|
for (var j = 0; j < methods.size(); j++) {
|
||||||
|
if (j == i) continue;
|
||||||
|
var m3 = resMeth2[j];
|
||||||
|
if (m3 == null) continue;
|
||||||
|
var m4 = resMeth1[j];
|
||||||
|
if (m4 == null) continue;
|
||||||
|
combinations.add(new Combination(m4, m3));
|
||||||
|
//System.out.println("Also Combining " + m4.getSignature() + " and " + m3.getSignature());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//System.out.println(" Not Combining " + m1.getSignature() + " and " + m2.getSignature());
|
||||||
|
}
|
||||||
|
if (!combinations.isEmpty()) allCombinations.add(combinations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
|
||||||
|
|
||||||
|
// Combine back into output format
|
||||||
|
var r0 = new HashSet<Set<TargetMethod>>();
|
||||||
|
for (var combinations : allCombinations) {
|
||||||
|
var r1 = new HashSet<Set<TargetMethod>>();
|
||||||
|
// This is used to weed out duplicates
|
||||||
|
var uniqued = new HashSet<TargetMethod>();
|
||||||
|
// We go over all methods in the result
|
||||||
|
for (var g : all) for (var i = 0; i < methods.size(); i++) {
|
||||||
|
var r2 = new HashSet<TargetMethod>();
|
||||||
|
var m = mapOfTargetMethods.get(g)[i];
|
||||||
|
if (m == null) continue;
|
||||||
|
if (!uniqued.contains(m)) {
|
||||||
|
// Add the method to r2
|
||||||
|
r2.add(m);
|
||||||
|
uniqued.add(m);
|
||||||
|
} else continue;
|
||||||
|
// Find all combinations that contain the method and add them to the result
|
||||||
|
// if not filtered out by uniqued
|
||||||
|
for (var c : combinations) {
|
||||||
|
if (c.a.equals(m) || c.b.equals(m)) {
|
||||||
|
if (!uniqued.contains(c.a)) {
|
||||||
|
r2.add(c.a);
|
||||||
|
uniqued.add(c.a);
|
||||||
|
}
|
||||||
|
if (!uniqued.contains(c.b)) {
|
||||||
|
r2.add(c.b);
|
||||||
|
uniqued.add(c.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r1.add(r2);
|
||||||
|
}
|
||||||
|
outer: for (var s1 : r1) {
|
||||||
|
for (var s2 : new HashSet<>(r0)) {
|
||||||
|
if (s2.containsAll(s1)) {
|
||||||
|
continue outer;
|
||||||
|
} else if (s1.containsAll(s2)) {
|
||||||
|
r0.remove(s2);
|
||||||
|
r0.add(s1);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r0.add(s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
||||||
|
|
||||||
|
System.out.println("============== OUTPUT ==============");
|
||||||
|
for (var l : result) {
|
||||||
|
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public TargetStructure convert(ClassOrInterface input) {
|
public TargetStructure convert(ClassOrInterface input) {
|
||||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||||
@@ -160,11 +377,12 @@ public class ASTToTargetAST {
|
|||||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
||||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
||||||
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
||||||
var methods = groupOverloads(input.getMethods()).stream().map(m -> convert(input, m)).flatMap(List::stream).toList();
|
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
|
||||||
|
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
|
||||||
|
|
||||||
TargetMethod staticConstructor = null;
|
TargetMethod staticConstructor = null;
|
||||||
if (input.getStaticInitializer().isPresent())
|
if (input.getStaticInitializer().isPresent())
|
||||||
staticConstructor = this.convert(input, input.getStaticInitializer().get()).get(0);
|
staticConstructor = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow().method;
|
||||||
|
|
||||||
if (input instanceof Record)
|
if (input instanceof Record)
|
||||||
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
@@ -174,9 +392,14 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
||||||
return input.getFormalparalist().stream().map(param ->
|
var res = new ArrayList<MethodParameter>();
|
||||||
new MethodParameter((TargetPattern) convert(param))
|
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
||||||
).toList();
|
var param = input.getFormalparalist().get(i);
|
||||||
|
var pattern = (TargetPattern) convert(param);
|
||||||
|
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
||||||
|
res.add(new MethodParameter(pattern));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
|
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
|
||||||
@@ -205,6 +428,7 @@ public class ASTToTargetAST {
|
|||||||
generics = all.get(0);
|
generics = all.get(0);
|
||||||
List<TargetConstructor> result = new ArrayList<>();
|
List<TargetConstructor> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
|
this.currentMethod = input;
|
||||||
|
|
||||||
for (var s : all) {
|
for (var s : all) {
|
||||||
generics = s;
|
generics = s;
|
||||||
@@ -224,111 +448,157 @@ public class ASTToTargetAST {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String encodeName(String name, TargetMethod.Signature params) {
|
||||||
* This only considers type patterns, all other methods aren't grouped together
|
|
||||||
* @param a
|
|
||||||
* @param b
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean signatureEquals(Method a, Method b) {
|
|
||||||
if (!a.name.equals(b.name)) return false;
|
|
||||||
var para = a.getParameterList().getFormalparalist();
|
|
||||||
var parb = b.getParameterList().getFormalparalist();
|
|
||||||
if (para.size() != parb.size()) return false;
|
|
||||||
|
|
||||||
for (var i = 0; i < para.size(); i++) {
|
|
||||||
var pa = para.get(i);
|
|
||||||
var pb = parb.get(i);
|
|
||||||
|
|
||||||
if (pa instanceof RecordPattern rpa) {
|
|
||||||
if (pb instanceof RecordPattern rpb) {
|
|
||||||
if (rpa.getType().equals(rpb.getType())) continue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (pa.getType().equals(pb.getType())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Nested patterns
|
|
||||||
private List<List<Method>> groupOverloads(List<Method> input) {
|
|
||||||
var done = new HashSet<Method>();
|
|
||||||
var res = new ArrayList<List<Method>>();
|
|
||||||
for (var method : input) {
|
|
||||||
if (done.contains(method)) continue;
|
|
||||||
var overloads = new ArrayList<Method>();
|
|
||||||
overloads.add(method);
|
|
||||||
done.add(method);
|
|
||||||
for (var method2 : input) {
|
|
||||||
if (!done.contains(method2) && signatureEquals(method, method2)) {
|
|
||||||
done.add(method2);
|
|
||||||
overloads.add(method2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.add(overloads);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String encodeName(String name, ParameterList params) {
|
|
||||||
var res = new StringBuilder();
|
var res = new StringBuilder();
|
||||||
res.append(name);
|
res.append(name);
|
||||||
res.append('$');
|
res.append('$');
|
||||||
for (var param : params.getFormalparalist()) {
|
for (var param : params.parameters()) {
|
||||||
if (param instanceof RecordPattern rp) {
|
encodeName(param.pattern(), res);
|
||||||
res.append(FunNGenerator.encodeType(convert(param.getType())));
|
|
||||||
for (var pattern : rp.getSubPattern()) {
|
|
||||||
res.append(FunNGenerator.encodeType(convert(pattern.getType())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res.toString();
|
return res.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetMethod> convert(ClassOrInterface clazz, List<Method> overloadedMethods) {
|
private void encodeName(TargetPattern pattern, StringBuilder res) {
|
||||||
if (overloadedMethods.size() == 1) {
|
if (pattern instanceof TargetComplexPattern cp) {
|
||||||
return convert(clazz, overloadedMethods.get(0));
|
res.append(FunNGenerator.encodeType(cp.type()));
|
||||||
|
for (var pat : cp.subPatterns()) {
|
||||||
|
encodeName(pat, res);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.append(FunNGenerator.encodeType(pattern.type()));
|
||||||
}
|
}
|
||||||
var res = new ArrayList<Method>();
|
}
|
||||||
for (var method : overloadedMethods) {
|
|
||||||
var newMethod = new Method(
|
private TargetType unwrap(TargetType type) {
|
||||||
method.modifier,
|
if (type instanceof TargetRefType ref) {
|
||||||
method.name,
|
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
|
||||||
//encodeName(method.name, method.getParameterList()),
|
}
|
||||||
method.getReturnType(),
|
return type;
|
||||||
method.getParameterList(),
|
}
|
||||||
method.block,
|
|
||||||
method.getGenerics(),
|
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||||
method.getOffset()
|
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||||
|
if (methods.size() == 1) {
|
||||||
|
var method = methods.getFirst();
|
||||||
|
var mParams = new ArrayList<TargetExpression>();
|
||||||
|
for (var i = 0; i < params.size(); i++) {
|
||||||
|
var tpe = method.signature().parameters().get(i).pattern().type();
|
||||||
|
mParams.add(new TargetLocalVar(tpe, params.get(i).name()));
|
||||||
|
}
|
||||||
|
TargetExpression caseBody = new TargetMethodCall(
|
||||||
|
method.signature().returnType(),
|
||||||
|
new TargetThis(classType),
|
||||||
|
mParams,
|
||||||
|
classType,
|
||||||
|
method.name(),
|
||||||
|
false, false, method.isPrivate()
|
||||||
);
|
);
|
||||||
res.add(newMethod);
|
if (method.signature().returnType() != null) {
|
||||||
|
caseBody = new TargetReturn(caseBody);
|
||||||
|
}
|
||||||
|
return caseBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Record overloading
|
var cases = new ArrayList<TargetSwitch.Case>();
|
||||||
/*var template = overloadedMethods.get(0);
|
var usedPatterns = new HashSet<TargetPattern>();
|
||||||
|
|
||||||
var pParams = new ArrayList<Pattern>();
|
for (var method : methods) {
|
||||||
var i = 0;
|
var patternsRec = new ArrayList<>(patterns);
|
||||||
for (var par : template.getParameterList()) {
|
|
||||||
pParams.add(switch (par) {
|
TargetExpression expr = null;
|
||||||
case RecordPattern rp -> new RecordPattern(rp.getSubPattern(), "par" + i, rp.getType(), new NullToken());
|
var i = 0;
|
||||||
default -> par;
|
for (var param : method.signature().parameters()) {
|
||||||
});
|
if (i == offset) {
|
||||||
i++;
|
patternsRec.add(param.pattern());
|
||||||
|
}
|
||||||
|
if (i > offset) {
|
||||||
|
// Find next pattern
|
||||||
|
expr = params.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastPattern = patternsRec.getLast();
|
||||||
|
if (usedPatterns.contains(lastPattern)) continue;
|
||||||
|
usedPatterns.add(lastPattern);
|
||||||
|
|
||||||
|
var candidates = methods.stream().filter(m -> {
|
||||||
|
var j = 0;
|
||||||
|
for (var param : m.signature().parameters()) {
|
||||||
|
if (j >= patternsRec.size()) return true;
|
||||||
|
if (!patternsRec.get(j).type().equals(param.pattern().type())) return false;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
|
||||||
|
var body = new TargetBlock(List.of(caseBody));
|
||||||
|
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
||||||
|
|
||||||
|
cases.add(case_);
|
||||||
}
|
}
|
||||||
var params = new ParameterList(pParams, new NullToken());
|
|
||||||
|
|
||||||
var statements = new ArrayList<Statement>();
|
return new TargetSwitch(switchExpr, cases, null, true);
|
||||||
statements.add(new Return(makeRecordSwitch(template.getReturnType(), params, res), new NullToken()));
|
}
|
||||||
var block = new Block(statements, new NullToken());
|
|
||||||
var entryPoint = new Method(template.modifier, template.name, template.getReturnType(), params, block, template.getGenerics(), new NullToken());
|
|
||||||
|
|
||||||
res.add(entryPoint); // TODO*/
|
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
||||||
return res.stream().map(m -> convert(clazz, m)).flatMap(List::stream).toList();
|
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
||||||
|
// Check if we have a pattern as a parameter
|
||||||
|
var firstMethod = overloadedMethods.getFirst();
|
||||||
|
var secondMethod = overloadedMethods.get(1);
|
||||||
|
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
|
||||||
|
// Rename existing methods
|
||||||
|
|
||||||
|
var res = new ArrayList<TargetMethod>();
|
||||||
|
for (var method : overloadedMethods) {
|
||||||
|
var name = encodeName(method.name(), method.signature());
|
||||||
|
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature()));
|
||||||
|
}
|
||||||
|
|
||||||
|
var signatureParams = new ArrayList<MethodParameter>();
|
||||||
|
for (var i = 0; i < firstMethod.signature().parameters().size(); i++) {
|
||||||
|
var p1 = firstMethod.signature().parameters().get(i).pattern();
|
||||||
|
var t1 = p1.type();
|
||||||
|
var t2 = secondMethod.signature().parameters().get(i).pattern().type();
|
||||||
|
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2));
|
||||||
|
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
||||||
|
var t3 = m.signature().parameters().get(i).pattern().type();
|
||||||
|
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
|
||||||
|
}
|
||||||
|
if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload");
|
||||||
|
// TODO accept multiple types
|
||||||
|
var superType = ASTFactory.createObjectClass();
|
||||||
|
if (!commonSubTypes.isEmpty())
|
||||||
|
superType = commonSubTypes.iterator().next();
|
||||||
|
|
||||||
|
String name;
|
||||||
|
if (p1 instanceof TargetComplexPattern) name = "__var" + i;
|
||||||
|
else name = p1.name();
|
||||||
|
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
|
||||||
|
}
|
||||||
|
|
||||||
|
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType()));
|
||||||
|
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
||||||
|
commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().returnType()));
|
||||||
|
}
|
||||||
|
var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString());
|
||||||
|
|
||||||
|
var parameters = signatureParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
||||||
|
//var patterns = List.of((TargetComplexPattern) firstMethod.signature().parameters().stream()
|
||||||
|
// .filter(p -> p.pattern() instanceof TargetComplexPattern).findFirst().orElseThrow().pattern());
|
||||||
|
|
||||||
|
// Generate dispatch method
|
||||||
|
var classType = new TargetRefType(clazz.getClassName().getClassName());
|
||||||
|
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType);
|
||||||
|
var block = new TargetBlock(List.of(stmt));
|
||||||
|
|
||||||
|
var signature = new TargetMethod.Signature(Set.of(), signatureParams, returnType);
|
||||||
|
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, signature, firstMethod.txSignature());
|
||||||
|
|
||||||
|
res.add(bridgeMethod);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
|
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
|
||||||
@@ -366,17 +636,35 @@ public class ASTToTargetAST {
|
|||||||
for (var i = 0; i < params.size(); i++) {
|
for (var i = 0; i < params.size(); i++) {
|
||||||
var a = TargetType.toPrimitive(params.get(i).pattern().type());
|
var a = TargetType.toPrimitive(params.get(i).pattern().type());
|
||||||
var b = convert(sParams.getFormalparalist().get(i).getType());
|
var b = convert(sParams.getFormalparalist().get(i).getType());
|
||||||
System.out.println(a + " " + b);
|
|
||||||
if (!Objects.equals(a, b)) return false;
|
if (!Objects.equals(a, b)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).findFirst();
|
}).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetMethod> convert(ClassOrInterface currentClass, Method method) {
|
record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
|
||||||
generics = all.get(0);
|
@Override
|
||||||
List<TargetMethod> result = new ArrayList<>();
|
public boolean equals(Object o) {
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof MethodWithTphs that)) return false;
|
||||||
|
return Objects.equals(method, that.method) && Objects.equals(args, that.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(method, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
|
||||||
|
|
||||||
|
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
||||||
|
generics = all.getFirst();
|
||||||
|
List<MethodWithTphs> result = new ArrayList<>();
|
||||||
|
this.currentMethod = method;
|
||||||
|
|
||||||
|
List<Signature> signatures = new ArrayList<>();
|
||||||
|
HashMap<TargetMethod.Signature, List<Generics>> collectedGenerics = new HashMap<>();
|
||||||
|
|
||||||
for (var s : all) {
|
for (var s : all) {
|
||||||
generics = s;
|
generics = s;
|
||||||
@@ -387,23 +675,37 @@ public class ASTToTargetAST {
|
|||||||
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params);
|
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params);
|
||||||
if (superMethod.isPresent()) {
|
if (superMethod.isPresent()) {
|
||||||
// If we find a super method to override, use its parameters and return types
|
// If we find a super method to override, use its parameters and return types
|
||||||
returnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
|
var newReturnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
|
||||||
params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
|
if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) {
|
||||||
|
returnType = newReturnType;
|
||||||
|
params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodParameter> finalParams = params;
|
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
|
||||||
if (parameterSet.stream().noneMatch(p -> p.equals(finalParams))) {
|
|
||||||
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
|
|
||||||
|
|
||||||
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
|
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
|
||||||
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
||||||
|
|
||||||
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
||||||
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
|
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
|
||||||
result.add(new TargetMethod(method.modifier, method.name, convert(method.block), javaSignature, txSignature));
|
|
||||||
parameterSet.add(params);
|
signatures.add(new Signature(javaSignature, txSignature, generics));
|
||||||
}
|
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
|
||||||
|
listOfGenerics.add(generics);
|
||||||
|
collectedGenerics.put(javaSignature, listOfGenerics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var signature : signatures) {
|
||||||
|
generics = signature.generics;
|
||||||
|
currentMethodOverloads = collectedGenerics.get(signature.java);
|
||||||
|
|
||||||
|
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
|
||||||
|
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
|
||||||
|
|
||||||
|
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +713,9 @@ public class ASTToTargetAST {
|
|||||||
var list = new ArrayList<MethodParameter>();
|
var list = new ArrayList<MethodParameter>();
|
||||||
for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
|
for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
|
||||||
var param = paraList.getParameterAt(i);
|
var param = paraList.getParameterAt(i);
|
||||||
list.add(new MethodParameter((TargetPattern) convert(param)).withType(convert(superList.getParameterAt(i).getType(), generics)));
|
var pattern = (TargetPattern) convert(param);
|
||||||
|
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
||||||
|
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -473,10 +777,59 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
var filteredParams = new ArrayList<TargetType>();
|
var filteredParams = new ArrayList<TargetType>();
|
||||||
for (var i = 0; i < newParams.size(); i++) {
|
for (var i = 0; i < newParams.size(); i++) {
|
||||||
if (gep.parameters.get(i) != null)
|
if (i < gep.inParams.size() && gep.inParams.get(i) != null)
|
||||||
filteredParams.add(newParams.get(i));
|
filteredParams.add(newParams.get(i));
|
||||||
}
|
}
|
||||||
return TargetFunNType.fromParams(params, filteredParams);
|
return TargetFunNType.fromParams(params, filteredParams, gep.getReturnType() != null ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FunNGenerator.GenericParameters convertToParameters(TargetFunNType input) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSubtype(TargetType test, TargetType other) {
|
||||||
|
if (other.equals(TargetType.Object)) return true;
|
||||||
|
if (test instanceof TargetFunNType tfun && other instanceof TargetFunNType ofun)
|
||||||
|
return isSubtype(new FunNGenerator.GenericParameters(tfun), new FunNGenerator.GenericParameters(ofun));
|
||||||
|
|
||||||
|
var testClass = compiler.getClass(new JavaClassName(test.name()));
|
||||||
|
var otherClass = compiler.getClass(new JavaClassName(other.name()));
|
||||||
|
if (testClass == null) return false;
|
||||||
|
while (testClass != null) {
|
||||||
|
if (testClass.equals(otherClass)) return true;
|
||||||
|
if (testClass.getClassName().equals(new JavaClassName("java.lang.Object"))) break;
|
||||||
|
testClass = compiler.getClass(testClass.getSuperClass().getName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSupertype(TargetType test, TargetType other) {
|
||||||
|
return isSubtype(other, test);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSubtype(FunNGenerator.GenericParameters test, FunNGenerator.GenericParameters other) {
|
||||||
|
if (test.getArguments().size() != other.getArguments().size()) return false;
|
||||||
|
if (!isSubtype(test.getReturnType(), other.getReturnType())) return false;
|
||||||
|
for (int i = 0; i < test.getArguments().size(); i++) {
|
||||||
|
var arg1 = test.getArguments().get(i);
|
||||||
|
var arg2 = other.getArguments().get(i);
|
||||||
|
if (!isSupertype(arg1, arg2)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateFunNTypes() {
|
||||||
|
for (var entry : usedFunN.entrySet()) {
|
||||||
|
var gep = entry.getValue();
|
||||||
|
var superInterfaces = usedFunN.values().stream()
|
||||||
|
.filter(g -> !g.equals(gep))
|
||||||
|
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
||||||
|
.map(FunNGenerator::getSpecializedClassName)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
||||||
|
auxiliaries.put(entry.getKey(), code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||||
@@ -491,39 +844,29 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var params = refType.getParaList().stream().map(type -> {
|
var params = refType.getParaList().stream().map(type -> {
|
||||||
var res = convert(type, generics);
|
return convert(type, generics);
|
||||||
if (res == null) res = new TargetRefType("java.lang.Void");
|
|
||||||
return res;
|
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
var returnType = FunNGenerator.getReturnType(params);
|
||||||
|
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
if (!usedFunNSuperTypes.contains(params.size())) {
|
||||||
usedFunNSuperTypes.add(params.size());
|
usedFunNSuperTypes.add(params.size());
|
||||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1);
|
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1);
|
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
try {
|
try {
|
||||||
classLoader.findClass(superClassName);
|
classLoader.findClass(superClassName);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
classLoader.loadClass(code);
|
classLoader.loadClass(superClassName, code);
|
||||||
} catch (LinkageError ignored) {}
|
} catch (LinkageError ignored) {}
|
||||||
}
|
}
|
||||||
auxiliaries.put(superClassName, code);
|
auxiliaries.put(superClassName, code);
|
||||||
}
|
}
|
||||||
FunNGenerator.GenericParameters gep = null;
|
FunNGenerator.GenericParameters gep = null;
|
||||||
if (!usedFunN.containsKey(className)) {
|
if (!usedFunN.containsKey(className)) {
|
||||||
gep = new FunNGenerator.GenericParameters();
|
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||||
var code = FunNGenerator.generateSpecializedBytecode(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params), gep);
|
|
||||||
try {
|
|
||||||
classLoader.findClass(className);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
try {
|
|
||||||
classLoader.loadClass(code);
|
|
||||||
} catch (LinkageError ignored) {}
|
|
||||||
}
|
|
||||||
usedFunN.put(className, gep);
|
usedFunN.put(className, gep);
|
||||||
auxiliaries.put(className, code);
|
|
||||||
} else {
|
} else {
|
||||||
gep = usedFunN.get(className);
|
gep = usedFunN.get(className);
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
@@ -134,8 +131,8 @@ public abstract class GenerateGenerics {
|
|||||||
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
|
final Map<Method, Set<Pair>> familyOfMethods = new HashMap<>();
|
||||||
|
|
||||||
final Set<PairLT> simplifiedConstraints = new HashSet<>();
|
final Set<PairLT> simplifiedConstraints = new HashSet<>();
|
||||||
final Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||||
final Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||||
|
|
||||||
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
||||||
this.astToTargetAST = astToTargetAST;
|
this.astToTargetAST = astToTargetAST;
|
||||||
@@ -154,6 +151,41 @@ public abstract class GenerateGenerics {
|
|||||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
|
||||||
|
|
||||||
|
public GenericsState store() {
|
||||||
|
return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restore(GenericsState state) {
|
||||||
|
this.concreteTypes = state.concreteTypes;
|
||||||
|
this.equality = state.equality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOverlay(TypePlaceholder from, RefTypeOrTPHOrWildcardOrGeneric to) {
|
||||||
|
if (to instanceof TypePlaceholder t) equality.put(from, t);
|
||||||
|
else if (to instanceof RefType t) concreteTypes.put(new TPH(from), t);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Set<TPH> findTypeVariables(ParameterList params) {
|
||||||
|
var res = new HashSet<TPH>();
|
||||||
|
for (var param : params.getFormalparalist()) {
|
||||||
|
res.addAll(findTypeVariables(param));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<TPH> findTypeVariables(Pattern pattern) {
|
||||||
|
var res = new HashSet<TPH>();
|
||||||
|
if (pattern instanceof RecordPattern rp) {
|
||||||
|
for (var subPattern : rp.getSubPattern()) {
|
||||||
|
res.addAll(findTypeVariables(subPattern));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.addAll(findTypeVariables(pattern.getType()));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Set<TPH> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) {
|
Set<TPH> findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
var result = new HashSet<TPH>();
|
var result = new HashSet<TPH>();
|
||||||
if (type instanceof TypePlaceholder tph) {
|
if (type instanceof TypePlaceholder tph) {
|
||||||
@@ -490,9 +522,7 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
if (!(method instanceof Constructor))
|
if (!(method instanceof Constructor))
|
||||||
typeVariables.addAll(findTypeVariables(method.getReturnType()));
|
typeVariables.addAll(findTypeVariables(method.getReturnType()));
|
||||||
for (var arg : method.getParameterList().getFormalparalist()) {
|
typeVariables.addAll(findTypeVariables(method.getParameterList()));
|
||||||
typeVariables.addAll(findTypeVariables(arg.getType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method.block != null)
|
if (method.block != null)
|
||||||
method.block.accept(new TracingStatementVisitor() {
|
method.block.accept(new TracingStatementVisitor() {
|
||||||
@@ -556,9 +586,7 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
var usedTphs = new HashSet<TPH>();
|
var usedTphs = new HashSet<TPH>();
|
||||||
// For eliminating inner type variables we need to figure out which ones are actually used
|
// For eliminating inner type variables we need to figure out which ones are actually used
|
||||||
for (var param : method.getParameterList().getFormalparalist()) {
|
usedTphs.addAll(findTypeVariables(method.getParameterList()));
|
||||||
usedTphs.addAll(findTypeVariables(param.getType()));
|
|
||||||
}
|
|
||||||
usedTphs.addAll(findTypeVariables(method.getReturnType()));
|
usedTphs.addAll(findTypeVariables(method.getReturnType()));
|
||||||
referenced.addAll(usedTphs);
|
referenced.addAll(usedTphs);
|
||||||
referenced.addAll(typeVariablesOfClass);
|
referenced.addAll(typeVariablesOfClass);
|
||||||
@@ -652,17 +680,25 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
||||||
outer:
|
for (var p1 : new HashSet<>(result)) {
|
||||||
|
if (p1 instanceof PairLT ptph && ptph.left.resolve().equals(ptph.right.resolve()))
|
||||||
|
result.remove(p1); // TODO This is a bit strange
|
||||||
|
}
|
||||||
for (var tph : usedTphs) {
|
for (var tph : usedTphs) {
|
||||||
for (var p1 : new HashSet<>(result)) {
|
|
||||||
if (p1 instanceof PairLT ptph && ptph.left.equals(ptph.right))
|
|
||||||
result.remove(p1); // TODO This is a bit strange
|
|
||||||
if (p1.left.equals(tph)) continue outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
|
if (classGenerics == null || classGenerics.stream().noneMatch((pair) -> pair.left.equals(tph)))
|
||||||
addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT));
|
addToPairs(result, new PairEQ(tph, ASTToTargetAST.OBJECT));
|
||||||
}
|
}
|
||||||
|
var all = new HashSet<>(result);
|
||||||
|
for (var p : all) {
|
||||||
|
if (p instanceof PairEQ peq && peq.right.equals(ASTToTargetAST.OBJECT)) {
|
||||||
|
for (var p2 : all) {
|
||||||
|
if (p2 instanceof PairLT && p2.left.equals(p.left)) {
|
||||||
|
result.remove(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ToAdd(TypePlaceholder left, TypePlaceholder right) {}
|
private record ToAdd(TypePlaceholder left, TypePlaceholder right) {}
|
||||||
|
@@ -1,24 +1,22 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.PrimitiveMethodsGenerator;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||||
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
|
||||||
import de.dhbwstuttgart.target.tree.TargetMethod;
|
import de.dhbwstuttgart.target.tree.TargetMethod;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
|
|
||||||
import javax.swing.text.html.Option;
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.sql.Array;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
public class StatementToTargetExpression implements ASTVisitor {
|
public class StatementToTargetExpression implements ASTVisitor {
|
||||||
@@ -35,54 +33,71 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LambdaCaptureFinder extends TracingStatementVisitor {
|
||||||
|
|
||||||
|
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
|
||||||
|
final Stack<Set<String>> localVariables = new Stack<>();
|
||||||
|
private final List<MethodParameter> parameters;
|
||||||
|
private final List<MethodParameter> captures;
|
||||||
|
|
||||||
|
LambdaCaptureFinder(List<MethodParameter> parameters, List<MethodParameter> captures) {
|
||||||
|
localVariables.push(new HashSet<>());
|
||||||
|
this.parameters = parameters;
|
||||||
|
this.captures = captures;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasLocalVar(String name) {
|
||||||
|
for (var localVariables : this.localVariables) {
|
||||||
|
if (localVariables.contains(name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Block block) {
|
||||||
|
localVariables.push(new HashSet<>());
|
||||||
|
super.visit(block);
|
||||||
|
localVariables.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LocalVar localVar) {
|
||||||
|
super.visit(localVar);
|
||||||
|
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
|
||||||
|
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
||||||
|
captures.add(capture);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LocalVarDecl varDecl) {
|
||||||
|
var localVariables = this.localVariables.peek();
|
||||||
|
localVariables.add(varDecl.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LambdaExpression lambda) {
|
||||||
|
var newCaptures = new ArrayList<MethodParameter>();
|
||||||
|
var captureFinder = new LambdaCaptureFinder(createParameters(lambda), newCaptures);
|
||||||
|
lambda.methodBody.accept(captureFinder);
|
||||||
|
newCaptures.removeAll(parameters);
|
||||||
|
captures.addAll(newCaptures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MethodParameter> createParameters(LambdaExpression lambda) {
|
||||||
|
return StreamSupport.stream(lambda.params.spliterator(), false)
|
||||||
|
.map(p -> (FormalParameter) p)
|
||||||
|
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false)
|
var parameters = createParameters(lambdaExpression);
|
||||||
.map(p -> (FormalParameter) p)
|
|
||||||
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
List<MethodParameter> captures = new ArrayList<>();
|
List<MethodParameter> captures = new ArrayList<>();
|
||||||
lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
|
var visitor = new LambdaCaptureFinder(parameters, captures);
|
||||||
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
|
lambdaExpression.methodBody.accept(visitor);
|
||||||
final Stack<Set<String>> localVariables = new Stack<>();
|
|
||||||
{
|
|
||||||
localVariables.push(new HashSet<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasLocalVar(String name) {
|
|
||||||
for (var localVariables : this.localVariables) {
|
|
||||||
if (localVariables.contains(name))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(Block block) {
|
|
||||||
localVariables.push(new HashSet<>());
|
|
||||||
super.visit(block);
|
|
||||||
localVariables.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVar localVar) {
|
|
||||||
super.visit(localVar);
|
|
||||||
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
|
|
||||||
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
|
||||||
captures.add(capture);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LocalVarDecl varDecl) {
|
|
||||||
var localVariables = this.localVariables.peek();
|
|
||||||
localVariables.add(varDecl.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(LambdaExpression lambda) {
|
|
||||||
} // Don't look at lambda expressions
|
|
||||||
});
|
|
||||||
|
|
||||||
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType()));;
|
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType()));;
|
||||||
var tpe = converter.convert(lambdaExpression.getType());
|
var tpe = converter.convert(lambdaExpression.getType());
|
||||||
@@ -123,7 +138,10 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BoolExpression bool) {
|
public void visit(BoolExpression bool) {
|
||||||
System.out.println("BoolExpression");
|
result = switch(bool.operation) {
|
||||||
|
case OR -> new TargetBinaryOp.Or(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
||||||
|
case AND -> new TargetBinaryOp.And(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,7 +161,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), fieldVar.isStatic, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
|
var isStatic = false;
|
||||||
|
var type = converter.convert(fieldVar.receiver.getType());
|
||||||
|
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
|
||||||
|
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
|
||||||
|
result = new TargetFieldVar(converter.convert(fieldVar.getType()), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -208,6 +230,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
var isPrivate = false;
|
var isPrivate = false;
|
||||||
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
|
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
|
||||||
|
|
||||||
|
// Add used TPHs to containing method
|
||||||
|
for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
|
||||||
|
converter.addSignaturePair(methodCall.signatureArguments().get(i), methodCall.arglist.getArguments().get(i).getType());
|
||||||
|
}
|
||||||
|
|
||||||
var receiverClass = converter.compiler.getClass(receiverName);
|
var receiverClass = converter.compiler.getClass(receiverName);
|
||||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver && expressionReceiver.expr instanceof This) {
|
||||||
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
|
if (receiverClass == null) throw new DebugException("Class " + receiverName + " does not exist!");
|
||||||
@@ -228,6 +255,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
isInterface = receiverClass.isInterface();
|
isInterface = receiverClass.isInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println(argList);
|
||||||
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface, isPrivate);
|
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface, isPrivate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,6 +288,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
result = new TargetBreak();
|
result = new TargetBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
result = new TargetContinue();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
||||||
@@ -282,7 +315,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
throw new NotImplementedException();
|
result = new TargetDo(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO These two might not be necessary
|
// TODO These two might not be necessary
|
||||||
@@ -375,9 +408,94 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
|
result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {}
|
||||||
|
|
||||||
|
private List<TypeVariants> extractAllPatterns(Pattern pattern) {
|
||||||
|
return switch (pattern) {
|
||||||
|
case GuardedPattern guarded -> extractAllPatterns(guarded.getNestedPattern());
|
||||||
|
case RecordPattern recordPattern -> recordPattern.getSubPattern().stream()
|
||||||
|
.map(this::extractAllPatterns)
|
||||||
|
.flatMap(List::stream).toList();
|
||||||
|
case FormalParameter param -> List.of(new TypeVariants(param.getType(), converter.findAllVariants(param.getType())));
|
||||||
|
default -> List.of();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
record TypePair(RefTypeOrTPHOrWildcardOrGeneric in, RefTypeOrTPHOrWildcardOrGeneric out) {}
|
||||||
|
|
||||||
|
private void cartesianProduct(
|
||||||
|
List<TypeVariants> variants, int index,
|
||||||
|
List<RefTypeOrTPHOrWildcardOrGeneric> current,
|
||||||
|
List<List<RefTypeOrTPHOrWildcardOrGeneric>> result) {
|
||||||
|
|
||||||
|
if (index == variants.size()) {
|
||||||
|
result.add(new ArrayList<>(current));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var currentSet = variants.get(index).types;
|
||||||
|
for (var element: currentSet) {
|
||||||
|
current.add(element);
|
||||||
|
cartesianProduct(variants, index + 1, current, result);
|
||||||
|
current.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<TypePair>> cartesianProduct(List<TypeVariants> variants) {
|
||||||
|
var prod = new ArrayList<List<RefTypeOrTPHOrWildcardOrGeneric>>();
|
||||||
|
cartesianProduct(variants, 0, new ArrayList<>(), prod);
|
||||||
|
|
||||||
|
var res = new ArrayList<List<TypePair>>();
|
||||||
|
for (var list : prod) {
|
||||||
|
var l = new ArrayList<TypePair>();
|
||||||
|
for (var i = 0; i < list.size(); i++) {
|
||||||
|
l.add(new TypePair(variants.get(i).in, list.get(i)));
|
||||||
|
}
|
||||||
|
res.add(l);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Switch switchStmt) {
|
public void visit(Switch switchStmt) {
|
||||||
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList();
|
var variants = converter.findAllVariants(switchStmt.getSwitch().getType());
|
||||||
|
var returns = converter.findAllVariants(switchStmt.getType());
|
||||||
|
var canBeOverloaded = variants.size() == 1 && returns.size() == 1;
|
||||||
|
|
||||||
|
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(case_ -> {
|
||||||
|
var overloads = new ArrayList<TargetSwitch.Case>();
|
||||||
|
|
||||||
|
if (canBeOverloaded) {
|
||||||
|
for (var label: case_.getLabels()) {
|
||||||
|
var product = cartesianProduct(extractAllPatterns(label.getPattern()));
|
||||||
|
|
||||||
|
for (var l : product) {
|
||||||
|
var oldGenerics = converter.generics;
|
||||||
|
|
||||||
|
// Set the generics to matching result set
|
||||||
|
for (var generics : converter.currentMethodOverloads) {
|
||||||
|
var java = generics.javaGenerics();
|
||||||
|
var equals = true;
|
||||||
|
for (var pair : l) {
|
||||||
|
if (!java.getType(pair.in).equals(pair.out)) {
|
||||||
|
equals = false; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (equals) {
|
||||||
|
converter.generics = generics;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overloads.add(converter.convert(case_));
|
||||||
|
converter.generics = oldGenerics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
overloads.add(converter.convert(case_));
|
||||||
|
}
|
||||||
|
|
||||||
|
return overloads;
|
||||||
|
}).flatMap(List::stream).toList();
|
||||||
|
|
||||||
TargetSwitch.Case default_ = null;
|
TargetSwitch.Case default_ = null;
|
||||||
for (var block : switchStmt.getBlocks()) {
|
for (var block : switchStmt.getBlocks()) {
|
||||||
@@ -471,6 +589,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
|
result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LiteralPattern literalPattern) {
|
||||||
|
result = new TargetExpressionPattern(converter.convert(literalPattern.value));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ExpressionPattern aPattern) {
|
public void visit(ExpressionPattern aPattern) {
|
||||||
result = converter.convert(aPattern.getExpression());
|
result = converter.convert(aPattern.getExpression());
|
||||||
|
@@ -124,6 +124,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
|
@@ -11,4 +11,8 @@ public record MethodParameter(TargetPattern pattern) {
|
|||||||
public MethodParameter withType(TargetType type) {
|
public MethodParameter withType(TargetType type) {
|
||||||
return new MethodParameter(pattern.withType(type));
|
return new MethodParameter(pattern.withType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodParameter withName(String name) {
|
||||||
|
return new MethodParameter(pattern.withName(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
|||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature) {
|
public record TargetMethod(int access, String name, TargetBlock block, Signature signature, Signature txSignature) {
|
||||||
@@ -17,6 +18,19 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
|||||||
public String getDescriptor() {
|
public String getDescriptor() {
|
||||||
return TargetMethod.getDescriptor(returnType, parameters.stream().map(MethodParameter::pattern).map(TargetPattern::type).toArray(TargetType[]::new));
|
return TargetMethod.getDescriptor(returnType, parameters.stream().map(MethodParameter::pattern).map(TargetPattern::type).toArray(TargetType[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Signature signature = (Signature) o;
|
||||||
|
return Objects.equals(parameters, signature.parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
||||||
@@ -64,5 +78,20 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
|||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return (access & Opcodes.ACC_STATIC) != 0;
|
return (access & Opcodes.ACC_STATIC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPrivate() {
|
||||||
|
return (access & Opcodes.ACC_PRIVATE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (!(other instanceof TargetMethod otherMethod)) return false;
|
||||||
|
return otherMethod.signature.equals(this.signature) && otherMethod.name.equals(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, signature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,4 +9,9 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
|
|||||||
public TargetComplexPattern withType(TargetType type) {
|
public TargetComplexPattern withType(TargetType type) {
|
||||||
return new TargetComplexPattern(type, name, subPatterns);
|
return new TargetComplexPattern(type, name, subPatterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetComplexPattern withName(String name) {
|
||||||
|
return new TargetComplexPattern(type, name, subPatterns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
|
public record TargetDo(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
||||||
|
}
|
@@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression;
|
|||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
|
|
||||||
public sealed interface TargetExpression
|
public sealed interface TargetExpression
|
||||||
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
||||||
|
|
||||||
default TargetType type() {
|
default TargetType type() {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
|
public record TargetExpressionPattern(TargetExpression expression) implements TargetPattern {
|
||||||
|
@Override
|
||||||
|
public TargetPattern withType(TargetType type) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetType type() {
|
||||||
|
return expression.type();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetPattern withName(String name) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@@ -12,4 +12,9 @@ public record TargetGuard(TargetPattern inner, TargetExpression expression) impl
|
|||||||
public TargetType type() {
|
public TargetType type() {
|
||||||
return inner.type();
|
return inner.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetGuard withName(String name) {
|
||||||
|
return new TargetGuard(inner.withName(name), expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@ package de.dhbwstuttgart.target.tree.expression;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetGuard, TargetTypePattern {
|
public sealed interface TargetPattern extends TargetExpression permits TargetComplexPattern, TargetExpressionPattern, TargetGuard, TargetTypePattern {
|
||||||
default String name() {
|
default String name() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,6 @@ public sealed interface TargetPattern extends TargetExpression permits TargetCom
|
|||||||
TargetPattern withType(TargetType type);
|
TargetPattern withType(TargetType type);
|
||||||
|
|
||||||
TargetType type();
|
TargetType type();
|
||||||
|
|
||||||
|
TargetPattern withName(String name);
|
||||||
}
|
}
|
||||||
|
@@ -7,4 +7,9 @@ public record TargetTypePattern(TargetType type, String name) implements TargetP
|
|||||||
public TargetTypePattern withType(TargetType type) {
|
public TargetTypePattern withType(TargetType type) {
|
||||||
return new TargetTypePattern(type, name);
|
return new TargetTypePattern(type, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetTypePattern withName(String name) {
|
||||||
|
return new TargetTypePattern(type, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
package de.dhbwstuttgart.target.tree.expression;
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
|
||||||
|
|
||||||
public record TargetWhile(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
public record TargetWhile(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,29 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public record TargetFunNType(String name, List<TargetType> params) implements TargetSpecializedType {
|
public record TargetFunNType(String name, List<TargetType> funNParams, List<TargetType> params, int returnArguments) implements TargetSpecializedType {
|
||||||
|
|
||||||
public static TargetFunNType fromParams(List<TargetType> params) {
|
public static TargetFunNType fromParams(List<TargetType> params, int returnArguments) {
|
||||||
return fromParams(params, params);
|
return fromParams(params, params, returnArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams) {
|
public static TargetFunNType fromParams(List<TargetType> params, List<TargetType> realParams, int returnArguments) {
|
||||||
var name = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
var name = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), FunNGenerator.getReturnType(params));
|
||||||
return new TargetFunNType(name, realParams);
|
return new TargetFunNType(name, params, realParams, returnArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toMethodDescriptor() {
|
||||||
|
var res = "(";
|
||||||
|
for (var i = 0; i < funNParams.size() - 1; i++) {
|
||||||
|
res += "Ljava/lang/Object;";
|
||||||
|
}
|
||||||
|
res += ")";
|
||||||
|
if (returnArguments > 0) {
|
||||||
|
res += "Ljava/lang/Object;";
|
||||||
|
} else {
|
||||||
|
res += "V";
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user